Javax Websocket 由于非法 UTF-8 序列而关闭

标签 java utf-8 websocket glassfish tyrus

我正在用 Java 编写 Websocket 客户端,使用 javax.websocket API 和 org.glassfish.tyrus 作为实现。

通常一切正常,但有时,当我收到非常大的字符串时,连接会以神秘的“非法 UTF-8 序列”作为关闭原因关闭。

log.info("Ws closed cuz: " 
   + reason.getCloseCode() + " , " 
   + reason.getReasonPhrase() + " , " 
   + reason.toString());

输出:

INFO: Ws closed cuz: NOT_CONSISTENT , Illegal UTF-8 Sequence ,
CloseReason[1007,Illegal UTF-8 Sequence]

我猜测要么是字符串太大,要么是字符串包含任何不兼容 UTF-8 的字符。

有没有办法获取有关导致此问题的实际字符串/数据包/帧的更多信息?或者,如果有办法告诉 tyrus 忽略任何编码问题,只将原始字符串传递给我并让我处理它?<​​/p>

如果没有,是否有另一个 java websockets 客户端可以完成通过套接字传输字符串的基本工作,并且不进行任何验证,只让我处理响应?

感谢任何反馈。

最佳答案

以下仅为猜测

(1) 在服务器端,大字符串被拆分为一个文本框和一个或多个后续的延续框。从技术上讲,将原始大字符串转换为字节数组,然后将字节数组拆分为多个子字节数组。子数组一一设置为帧(=每一帧包含一个子字节数组)。

(2) 虽然不能保证每个子字节数组都是有效的UTF-8序列,但是在服务器端或客户端都会进行有效性检查。如果是这样,那就是 Tyrus 的错误。

WebSocketListenernv-websocket-client具有帧粒度的回调方法,例如 onFrameonTextFrameonContinuationFrame 等(注意 onTextMessageonTextFrame 不同),因此您可以在那里检查每个帧的字节数组。

WebSocket websocket = new WebSocketFactory()
    .createSocket("ws://...")
    .addListener(new WebSocketAdapter() {
        @Override
        public void onFrame(WebSocket ws, WebSocketFrame frame) {
            // If the frame is a text frame with FIN bit cleared, or
            // if the frame is a continuation frame.
            if ((frame.isTextFrame() && frame.getFin() == false) ||
                frame.isContinuationFrame()) {
                // The payload of the frame. There is no guarantee
                // that this byte array is a valid UTF-8 sequence.
                byte[] payload = frame.getPayload();

                // Check whether the payload is a valid UTF-8 sequence
                // if you want to.
                checkPayload(payload);
            }
        }
    })
    .connect();

你为什么不使用nv-websocket-client检查您的 WebSocket 连接中发生了什么?

关于Javax Websocket 由于非法 UTF-8 序列而关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32213497/

相关文章:

java - JTable 始终使用固定大小

java - 循环遍历迭代器后,我可以将其光标放在第一项之前的位置吗?

utf-8 - ColdFusion:将带重音的区域字符转换为纯ASCII

symfony - Websocket 无法在 Ubuntu 上打开端口

java - 当您需要创建一个指向变量的指针时,为什么指针可以节省内存?

字符串的java正则表达式

python - 使用 sqlalchemy 加载 UnicodeDecodeError

python - 使用 NumPy loadtxt/savetxt 指定编码

node.js - 如何使用 nginx 反向代理和 https 获取 socket.io 示例

json - 在 go websocket 服务器上获取 json 数据