微信小程序 websocket 获取不到 session ?
[@RequestMapping](/user/RequestMapping) ( "login" ) public ReturnValue login(HttpServletRequest request, HttpServletResponse response) throws Exception { String userId = request.getParameter( "userId" ); String proxyId=request.getParameter( "proxyId" ); String workOrderId=request.getParameter( "workOrderId" ); String clientType=request.getParameter( "clientType" ); if (Strings.isBlank(userId)||Strings.isBlank(proxyId)||Strings.isBlank(workOrderId)||Strings.isBlank(clientType)) { return new ReturnValue( false , "参数异常" ); } HttpSession session = request.getSession(); if ( null !=session) { System.out.println( "登陆WebSocket成功:" +( "1" .equals(clientType)? "P" +proxyId+workOrderId: "U" +userId+workOrderId)); session.setAttribute( "WEBSOCKET_SESSSION_ID" , "1" .equals(clientType)? "P" +proxyId+workOrderId: "U" +userId+workOrderId); //一般直接保存user实体 } else { System.out.println( "登陆WebSocket失败,session==null:" +( "1" .equals(clientType)? "P" +proxyId+workOrderId: "U" +userId+workOrderId)); logger.error( "登录websocket+login时,获取session失败" ); } return new ReturnValue( true ); } |
这是小程序登录websocket 时的代码,当在session 中设置好键值后,在spring tcp握手连接时得不到这个session 和其中的值。
下面是tcp 握手连接时的代码 ,就是得不到session ,但是浏览器端是可以的,因为他加了xhrFields 带了凭证可以保证得到的session是一致的,
var url="<%=afterSaleServer%>/ptt/controller/websocket/websocketcontroller/login"; $.ajax({ url: url, type: 'post', async:false, data: messageJsonLogin, xhrFields: { withCredentials: true//允许带上凭据 }, crossDomain: true, success:function(res){ if(res.code=="200"){ if ('WebSocket' in window) { ws = new WebSocket(""+socketUrl+"/ptt/websocket/socketServer"); console.log("连接成功"); } else if ('MozWebSocket' in window) { ws = new MozWebSocket(""+socketUrl+"/ptt/websocket/socketServer"); } else {// 这个是应对浏览器不支持websocket协议的时候降级为轮询的处理。 ws = new SockJS("https://"+socketUrl+"/ptt/sockjs/socketServer"); } } }, error:function(){ } }); |
[@Override](/user/Override) public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { System.out.println( "Before Handshake" ); if (request instanceof ServletServerHttpRequest) { ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; HttpSession session = servletRequest.getServletRequest().getSession(); System.out.println( "握手时,获取到的session:" +session); if (session != null ) { //使用拼接ID区分WebSocketHandler,以便定向发送消息 String sessionId = (String) session.getAttribute( "WEBSOCKET_SESSSION_ID" ); //一般直接保存user实体 if (sessionId!= null ) { attributes.put( "WEBSOCKET_SESSSION_ID" ,sessionId); } //使用拼接ID区分WebSocketHandler,以便定向发送消息 出来处理工单也,在主页面的socket String sessionNo_workOrderId = (String) session.getAttribute( "WEBSOCKET_NO_WORKORDER_WAIT_MESSAGE_SESSSION_ID" ); //一般直接保存user实体 if (sessionNo_workOrderId!= null ) { attributes.put( "WEBSOCKET_NO_WORKORDER_WAIT_MESSAGE_SESSSION_ID" ,sessionNo_workOrderId); } } } return super .beforeHandshake(request, response, wsHandler, attributes); } |
下面是小程序端的代码,虽然我每次请求都发送了sessionId, 但是都是没有用,就是获取不到session,为什么要获取这个session呢?
loginWebSocket({ workOrderId: workOrderId, userId: userId, proxyId: proxyId, clientType: clientType}).then( console.log("登陆成功"), wx.connectSocket({ url: "" + socketUrl + "/ptt/websocket/socketServer", success() { console.log('连接成功') that.initEventHandle() } }) ); |
initEventHandle() { let that = this wx.onSocketMessage((res) => { console.log("收到消息",res); //收到消息 if (res.data == "pong") { heartCheck.reset().start() } else { //处理数据 console.log(res.data); var nowDate2 = util.formatDate(new Date());//发送日期 var nowTime2 = util.formatNowTime(new Date());//发送时间 var messageJson2 = {}; messageJson2.content = res.data; messageJson2.makeDate = nowDate2; messageJson2.makeTime = nowTime2; messageJson2.proxyId = proxyId; messageJson2.userId = null; var array2 = that.data.leaveMsgList; array2.push(messageJson2); that.setData({ leaveMsgList: array2 }); that.toButtom(); } }) wx.onSocketOpen(() => { console.log('WebSocket连接打开') heartCheck.reset().start() }) wx.onSocketError((res) => { console.log('WebSocket连接打开失败') this.reconnect() }) wx.onSocketClose((res) => { console.log('WebSocket 已关闭!') this.reconnect() }) }, reconnect:function() { console.log(this.lockReconnect); if (this.lockReconnect) return; this.lockReconnect = true; console.log("...."); clearTimeout(this.timer) if (this.data.limit < 12 ) { this.timer = setTimeout (() => { this.linkWebSocket(); this.lockReconnect = false; }, 5000); this.setData({ limit: this.data.limit + 1 }) } }, |
因为要通过在session 中设置的值来往 集合中放入session,方便对这个session 发送消息
/** * 连接成功时候,会触发页面上onopen方法 */ [@Override](/user/Override) public void afterConnectionEstablished(WebSocketSession session) throws Exception { System.out.println( "成功建立websocket连接!" ); String userId = (String) session.getAttributes().get(USER_ID); String no_workOrderId_userId = (String) session.getAttributes().get(No_WORKORDER_USERID); System.out.println( "成功建立websocket连接 userId=!" +userId); System.out.println( "成功建立websocket连接no_workOrderId_userId=!" +no_workOrderId_userId); if (Strings.isNotBlank(userId)) { if (users.containsKey(userId)) { //如果已包含将关闭之前的session,发送消息到新的session WebSocketSession wss=users.get(userId); wss.close(); } users.put(userId,session); } if (Strings.isNotBlank(no_workOrderId_userId)) { if (users.containsKey(no_workOrderId_userId)) { //如果已包含将关闭之前的session,发送消息到新的session WebSocketSession wss=users.get(no_workOrderId_userId); wss.close(); } users.put(no_workOrderId_userId,session); } System.out.println( "当前线上用户数量:" +users.size()); users.entrySet().forEach(System.out::println); System.out.println( ".......以上为用户session数量" ); //这块会实现自己业务,比如,当用户登录后,会把离线消息推送给用户 //TextMessage returnMessage = new TextMessage("成功建立socket连接,你将收到的离线"); //session.sendMessage(returnMessage); } |
/** * 给某个用户发送消息 * * [@param](/user/param) userId * [@param](/user/param) message */ public void sendMessageToUser(String userId, TextMessage message) { logger.error( "开始发送消息!给->" +userId + " 信息" +message); for (String id : users.keySet()) { logger.error( "目前有:键值" +id+ " 会话" +users.get(id)); if (id.equals(userId)) { try { if (users.get(id).isOpen()) { users.get(id).sendMessage(message); logger.error( "成功发送消息给:" +userId); } } catch (IOException e) { e.printStackTrace(); } break ; } } } |
跪求大佬们,耽误好几天了,在开发工具当中没有问题,但是小程序到了真机和体验版时,一致有这个问题