一. 依赖(这里只列举了websocket相关依赖)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.tyrus.bundles</groupId>
<artifactId>tyrus-standalone-client</artifactId>
<version>1.13</version>
</dependency>
二. WebSocket服务端
2-1. 核心代码
package com.github.websocket.server;
import com.alibaba.fastjson.JSON;
import com.github.CommonConstant;
import com.github.session.SObject;
import com.github.websocket.configuration.HttpSessionConfigurator;
import com.github.websocket.msg.Msg;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@ServerEndpoint(value = "/chat", configurator = HttpSessionConfigurator.class)
public class WSServer {
static private Logger logger = Logger.getLogger(WSServer.class);
private static int onlineCount = 0;
static public final ConcurrentMap<String, WSServer> map = new ConcurrentHashMap<>();
private Session session;
private HttpSession httpSession;
@OnOpen
public void onOpen(Session session, EndpointConfig config) {
this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
SObject user = (SObject) this.httpSession.getAttribute(CommonConstant.USER_LOGIN_SESSION);
this.session = session;
map.put(user.getUid(), this);
addOnlineCount();
logger.info("有新的连接,当前连接数为:" + getOnlineCount());
}
@OnClose
public void onClose() {
SObject user = (SObject) this.httpSession.getAttribute(CommonConstant.USER_LOGIN_SESSION);
map.remove(user.getUid());
subOnlineCount();
logger.info("有一连接断开,当前连接数为:" + getOnlineCount());
}
@OnMessage
public void onMessage(String message) throws IOException {
Msg msg = JSON.parseObject(message, Msg.class);
WSServer _client = map.get(msg.getToUid());
if (StringUtils.isNotEmpty(msg.getToUid())) {
if (null != _client) {
if (_client.session.isOpen())
_client.session.getBasicRemote().sendText(JSON.toJSONString(msg));
}
}
if (StringUtils.isEmpty(msg.getToUid())) {
for (WSServer client : map.values()) {
client.session.getBasicRemote().sendText(JSON.toJSONString(msg));
}
}
}
@OnError
public void onError(Throwable t) {
logger.error(t);
t.printStackTrace();
}
static
public void pushBySys(Msg msg) {
for (WSServer client : map.values()) {
try {
client.session.getBasicRemote().sendText(JSON.toJSONString(msg));
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static synchronized int getOnlineCount() {
return WSServer.onlineCount;
}
private static synchronized void addOnlineCount() {
WSServer.onlineCount++;
}
private static synchronized void subOnlineCount() {
WSServer.onlineCount--;
}
}
2-2. HttpSessionConfigurator类
package com.github.websocket.configuration;
import javax.servlet.http.HttpSession;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import javax.websocket.server.ServerEndpointConfig.Configurator;
public class HttpSessionConfigurator extends Configurator {
@Override
public void modifyHandshake(ServerEndpointConfig sec,
HandshakeRequest request, HandshakeResponse response) {
HttpSession httpSession = (HttpSession) request.getHttpSession();
sec.getUserProperties().put(HttpSession.class.getName(), httpSession);
}
}
2-3. Msg消息体
package com.github.websocket.msg;
import java.util.Date;
public class Msg {
private String fromUid;
private String toUid;
private String toOrgId;
private String data;
private Date createDate = new Date();
private Integer flag;
public Msg() {
}
public Msg(String fromUid, String toUid, String toOrgId, String data, Date createDate, Integer flag) {
this.fromUid = fromUid;
this.toUid = toUid;
this.toOrgId = toOrgId;
this.data = data;
this.createDate = createDate;
this.flag = flag;
}
public String getFromUid() {
return fromUid;
}
public void setFromUid(String fromUid) {
this.fromUid = fromUid;
}
public String getToUid() {
return toUid;
}
public void setToUid(String toUid) {
this.toUid = toUid;
}
public String getToOrgId() {
return toOrgId;
}
public void setToOrgId(String toOrgId) {
this.toOrgId = toOrgId;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Integer getFlag() {
return flag;
}
public void setFlag(Integer flag) {
this.flag = flag;
}
@Override
public String toString() {
return "Msg{" +
"fromUid='" + fromUid + '\'' +
", toUid='" + toUid + '\'' +
", toOrgId='" + toOrgId + '\'' +
", data='" + data + '\'' +
", createDate=" + createDate +
", flag=" + flag +
'}';
}
}
三. 客户端(HTML5)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WebSocket</title>
<script type="text/javascript">
var ws = new WebSocket("ws://localhost:8080/chat");
ws.onopen = function(message) {
};
ws.onclose = function(message) {
};
ws.onmessage = function(message) {
showMessage(message.data);
};
window.onbeforeunload = function() {
ws.close();
};
function closeWebSocket() {
ws.close();
}
function send() {
var input = document.getElementById("msg");
var text = input.value;
var data = {
toUid : "3d535429-5fcb-4490-bcf7-96fd84bb17b6",
data : text
}
ws.send(JSON.stringify(data));
input.value = "";
}
function showMessage(message) {
var text = document.createTextNode(JSON.parse(message).data);
var br = document.createElement("br")
var div = document.getElementById("showChatMessage");
div.appendChild(text);
div.appendChild(br);
}
</script>
</head>
<body>
<div>
style="width: 600px; height: 240px; overflow-y: auto; border: 1px solid #333;"
id="show">
<div id="showChatMessage"></div>
<input type="text" size="80" id="msg" name="msg" placeholder="输入聊天内容" />
<input type="button" value="发送" id="sendBn" name="sendBn" onclick="send()">
</div>
</body>
</html>