1.环境描述
JeecgBoot3.0
2.websocket权限认证
- 在shiroConfig.java代码中注释掉
filterChainDefinitionMap.put("/websocket/**", "anon");//系统通知和公告
- 配置拦截器
package org.jeecg.config.websocket;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
@Component
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
return super.beforeHandshake(request, response, wsHandler, attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
HttpServletRequest httpServletRequest = ((ServletServerHttpRequest)request).getServletRequest();
HttpServletResponse httpServletResponse = ((ServletServerHttpResponse)response).getServletResponse();
if(StringUtils.isNotEmpty(httpServletRequest.getHeader("sec-websocket-protocol")))
httpServletResponse.addHeader("sec-websocket-protocol", httpServletRequest.getHeader("sec-websocket-protocol"));
super.afterHandshake(request, response, wsHandler, ex);
}
}
- 修改前端的请求,在HeaderNotice.vue中
let token = Vue.ls.get(ACCESS_TOKEN)
var url = window._CONFIG['domianURL'].replace("https://","wss://").replace("http://","ws://") "/websocket/" userId "?token=" token
3. HashMap不是线程安全的,可以改为线程安全的map,如下
代码语言:java复制 private static Map<String, Session> sessionPool = new ConcurrentHashMap<>();
4.重复发送问题
- 原有的代码为:
/**
* 服务器端推送消息
*/
public void pushMessage(String message) {
try {
webSockets.forEach(ws -> ws.session.getAsyncRemote().sendText(message));
} catch (Exception e) {
e.printStackTrace();
}
}
@OnMessage
public void onMessage(String message) {
//todo 现在有个定时任务刷,应该去掉
log.debug("【websocket消息】收到客户端消息:" message);
JSONObject obj = new JSONObject();
//业务类型
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK);
//消息内容
obj.put(WebsocketConst.MSG_TXT, "心跳响应");
for (WebSocket webSocket : webSockets) {
webSocket.pushMessage(message);
}
}
- 可将OnMessage函数改为:
@OnMessage
public void onMessage(String message) {
//todo 现在有个定时任务刷,应该去掉
log.debug("【websocket消息】收到客户端消息:" message);
JSONObject obj = new JSONObject();
//业务类型
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK);
//消息内容
obj.put(WebsocketConst.MSG_TXT, "心跳响应");
for (WebSocket webSocket : webSockets) {
//webSocket.pushMessage(message);
webSocket.session.getAsyncRemote().sendText(message);
}
}