Warm tip: This article is reproduced from serverfault.com, please click

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

(java - Javax Websocket closing due to Illegal UTF-8 Sequence)

发布于 2015-08-25 20:31:36

我正在使用javax.websocket API用Java编写Websocket客户端,并将其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忽略任何编码问题,而只将原始字符串传递给我,然后让我处理呢?

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

感谢任何反馈。

Questioner
Click Upvote
Viewed
1
Takahiko Kawasaki 2015-08-26 12:45:00

以下仅是一个猜测。

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

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

WebSocketListenerNV-的WebSocket客户端具有在帧粒度回调方法如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连接中发生了什么?