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

使用Java InputStreamReader读取JavaScript WebSocket消息乱码如何解决

WebSocket消息读取乱码解决方案

问题根源

  • WebSocket 不是裸TCP协议,通信分为两个阶段:
    1. 首先基于HTTP完成握手升级:客户端先发送带Upgrade: websocket头的HTTP请求,服务端按规范返回响应完成握手
    2. 握手成功后所有传输内容都按WebSocket帧格式编码,不是明文UTF-8字符串,直接用普通字符流读取必然出现乱码
      你当前使用的普通ServerSocket仅处理裸TCP连接,没有实现WebSocket握手和帧解析逻辑,因此无法正确解析前端发送的消息。

修复步骤

1. 修正前端连接协议

本地未配置SSL证书时,不要使用wss协议,修改连接地址为:

const socket = new WebSocket("ws://localhost:7999"); // 替换wss为ws

socket.addEventListener("open", (event) => {
    socket.send("Hello!");
});

socket.addEventListener("message", (event) => {
    console.log("Received message:", event.data);
});

2. 使用标准WebSocket服务端实现

无需手动实现复杂的握手和帧解析逻辑,直接使用成熟的 Jakarta WebSocket 参考实现 Tyrus 即可,步骤如下:

引入依赖(Maven示例)

<dependencies>
    <dependency>
        <groupId>org.glassfish.tyrus</groupId>
        <artifactId>tyrus-server</artifactId>
        <version>2.1.5</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.tyrus</groupId>
        <artifactId>tyrus-container-grizzly-server</artifactId>
        <version>2.1.5</version>
    </dependency>
</dependencies>

编写服务端代码

import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import org.glassfish.tyrus.server.Server;

@ServerEndpoint("/")
public class WebSocketDemoServer {

    @OnOpen
    public void handleConnectionOpen(Session session) {
        System.out.println("客户端已连接");
    }

    @OnMessage
    public void handleMessage(String message, Session session) {
        // 直接获取前端发送的明文字符串
        System.out.println("收到消息:" + message);
        // 可选:向客户端返回响应
        session.getAsyncRemote().sendText("消息接收成功");
    }

    @OnClose
    public void handleConnectionClose() {
        System.out.println("客户端已断开");
    }

    @OnError
    public void handleError(Throwable error) {
        error.printStackTrace();
    }

    public static void main(String[] args) throws Exception {
        Server server = new Server("localhost", 7999, "/", WebSocketDemoServer.class);
        try {
            server.start();
            System.out.println("服务端启动成功,端口7999");
            System.in.read(); // 阻塞保持服务运行
        } finally {
            server.stop();
        }
    }
}

运行服务端和前端代码后,即可在服务端控制台正常打印出前端发送的Hello!内容。
如果确实需要自行实现WebSocket协议逻辑,需要分别完成握手响应生成、帧数据解封装两个核心流程,实现成本较高,不推荐生产场景使用。

内容的提问来源于stack exchange,提问作者user7289922

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 19:36:04