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,如下
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); } }