本文参考:https://blog.youkuaiyun.com/fffvdgjvbsfkb123456/article/details/116465394
1.前端建立连接
注:前端不用单独引用额外的js组件,websocket是浏览器自带的组件,可以直接使用。
webSocketConnect: function (orderId) {
var host = window.location.host;
if ("WebSocket" in window) {
// 打开一个 web socket
ws = new WebSocket("ws://" + host + "/上下文/webSocketHandler?id=" + orderId);
ws.onmessage = function (evt) {
var received_msg = evt.data;
if("2"===received_msg){
$("#lose").show();
}
};
ws.onclose = function () {
// 关闭 websocket
console.log("连接已关闭");
};
} else {
// 浏览器不支持 WebSocket
layer.alert('不支持的浏览器!', {icon: 1});
}
},
2.关闭连接
closeWs: function () {
if (ws !== null) {
ws.close();
}
}
3.创建拦截器
public class WebSocketInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request;
// 获取参数
String id = serverHttpRequest.getServletRequest().getParameter("id");
attributes.put("currentId", id);
}
return true;
}
// 初次握手访问后
@Override
public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
}
}
4.配置文件
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
webSocketHandlerRegistry.addHandler(myHandler(),"/webSocketHandler").addInterceptors(new WebSocketInterceptor());
}
public WebSocketHandler myHandler(){
return new MessageHandler();
}
}
5.处理类
public class MessageHandler implements WebSocketHandler {
private static final Logger log = LoggerFactory.getLogger(MessageHandler.class);
/**
* WEB_SOCKET_MAP:使用线程安全map存储用户连接webscoket信息
*/
private final static Map<String, WebSocketSession> WEB_SOCKET_MAP = new ConcurrentHashMap<String, WebSocketSession>();
/**
* 关闭websocket时调用该方法
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
String id = this.getId(session);
if (StringUtils.isNoneBlank(id)) {
WEB_SOCKET_MAP.remove(id);
log.info(id + "已成功关闭");
} else {
log.info("关闭时,获取用户id为空");
}
}
/**
* 建立websocket连接时调用该方法
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
String id = this.getId(session);
if (StringUtils.isNoneBlank(id)) {
WEB_SOCKET_MAP.put(id, session);
session.sendMessage(new TextMessage("建立服务端连接成功!"));
}
}
/**
* 客户端调用websocket.send时候,会调用该方法,进行数据通信
*/
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
String msg = message.toString();
String id = this.getId(session);
log.info(id + "发送的消息是:" + msg);
message = new TextMessage("服务端已经接收到消息,msg=" + msg);
session.sendMessage(message);
}
/**
* 传输过程出现异常时,调用该方法
*/
@Override
public void handleTransportError(WebSocketSession session, Throwable e) throws Exception {
WebSocketMessage<String> message = new TextMessage("异常信息:" + e.getMessage());
session.sendMessage(message);
}
/**
* org.springframework.web.socket.WebSocketHandler#supportsPartialMessages()
*/
@Override
public boolean supportsPartialMessages() {
return false;
}
/**
* sendMessageToUser:发给指定用户
*/
public void sendMessageToUser(String id, String contents) {
WebSocketSession session = WEB_SOCKET_MAP.get(id);
if (session != null && session.isOpen()) {
try {
TextMessage message = new TextMessage(contents);
session.sendMessage(message);
} catch (Exception e) {
log.error("sendMessageToUser异常:"+"id="+id+",contents="+"contents",e);
}
}
}
/**
* sendMessageToAllUsers:发给所有的用户
*/
public void sendMessageToAllUsers(String contents) {
Set<String> ids = WEB_SOCKET_MAP.keySet();
for (String id : ids) {
this.sendMessageToUser(id, contents);
}
}
/**
* getUserId:获取用户id
*
* @param session
*/
private String getId(WebSocketSession session) {
try {
String id = (String) session.getAttributes().get("currentId");
return id;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}