You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 04:57:04