Spring Boot Jetty WebSocket客户端如何关联onMessage字符串与字节消息
解决方案
因为WebSocket协议天然保证同一个Session连接上的消息按发送顺序投递,你的服务器固定先发送字符串、再发送对应关联字节,所以可以通过Session暂存上下文的方式配对两类数据,具体实现如下:
实现逻辑
- 收到字符串消息时,将字符串元数据暂存到当前Session的属性中,等待对应字节消息到达
- 收到字节消息时,取出Session中暂存的字符串数据,即可完成配对处理
- 处理完成后清空暂存的上下文,等待下一组关联消息
完整修改后的代码
@OnWebSocketMessage public void onMessageString(Session session, String msg){ System.out.println("getRemoteAddress1:"+session.getRemoteAddress()); String vaHost = session.getRemoteAddress().toString().replaceAll("/", ""); System.out.printf("Got msg: %s%n",msg); // 暂存当前字符串元数据到Session属性 session.getUserProperties().put("relatedStringMeta", msg); session.getUserProperties().put("vaHost", vaHost); } @OnWebSocketMessage public void onMessageBuffer(Session session, byte[] byteArray, int offset, int length) throws IOException { System.out.println("onMessageBuffer"); System.out.println("getRemoteAddress2:"+session.getRemoteAddress()); // 取出关联的字符串元数据 String relatedMeta = (String) session.getUserProperties().get("relatedStringMeta"); String vaHost = (String) session.getUserProperties().get("vaHost"); // 异常兜底:如果没有对应字符串元数据,可按业务需求处理错误 if (relatedMeta == null) { System.err.println("收到无关联字符串的字节数据,已跳过处理"); return; } // 这里可直接关联使用两类数据,示例:将字符串元数据作为文件名标识 FileUtils.writeByteArrayToFile(new File("C:/files/ws/"+ relatedMeta + "_" + System.nanoTime() +".jpg"), byteArray); // 处理完成清空暂存,避免和下一组消息混淆 session.getUserProperties().remove("relatedStringMeta"); session.getUserProperties().remove("vaHost"); }
可选优化方案
如果存在多组消息并发的极端场景,可要求服务器在字符串消息中携带唯一标识,字节消息的前几位也携带相同标识,配对时校验标识即可完全避免错配。
内容的提问来源于stack exchange,提问作者Julia5049
相关产品推荐
相关产品推荐

