Javax Websocket 由于非法 UTF-8 序列而关闭
Javax Websocket closing due to Illegal UTF-8 Sequence
我正在 Java 中编写 Websocket 客户端,使用 javax.websocket API 和 org.glassfish.tyrus
作为实现。
通常一切正常,但有时,当我收到非常大的字符串时,连接会以神秘的 'Illegal UTF-8 Sequence' 作为关闭原因关闭。
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 客户端可以完成通过套接字传输字符串的基本工作,并且不进行任何验证,只让我处理响应?
感谢任何反馈。
以下仅为猜测
(1) 在服务器端,大字符串被拆分为一个文本框和一个或多个后续的延续框。从技术上讲,将原始大字符串转换为字节数组,然后将字节数组拆分为多个子字节数组。子数组一一设置为帧(=每一帧包含一个子字节数组)。
(2) 虽然不能保证每个子字节数组都是有效的UTF-8序列,但是无论是在服务器端还是在客户端都会进行有效性检查。如果是,那就是 Tyrus 的 bug。
WebSocketListener
of nv-websocket-client有onFrame
、onTextFrame
、onContinuationFrame
等帧粒度的回调方法(注意onTextMessage
和onTextFrame
不同),因此您可以在那里检查每个帧的字节数组。
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 连接中发生的情况?
我刚刚遇到了同样的错误。在我从 org.glassfish.tyrus
版本 1.1 更改为 2.0.0 后,它没有任何问题。
我正在 Java 中编写 Websocket 客户端,使用 javax.websocket API 和 org.glassfish.tyrus
作为实现。
通常一切正常,但有时,当我收到非常大的字符串时,连接会以神秘的 'Illegal UTF-8 Sequence' 作为关闭原因关闭。
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 客户端可以完成通过套接字传输字符串的基本工作,并且不进行任何验证,只让我处理响应?
感谢任何反馈。
以下仅为猜测
(1) 在服务器端,大字符串被拆分为一个文本框和一个或多个后续的延续框。从技术上讲,将原始大字符串转换为字节数组,然后将字节数组拆分为多个子字节数组。子数组一一设置为帧(=每一帧包含一个子字节数组)。
(2) 虽然不能保证每个子字节数组都是有效的UTF-8序列,但是无论是在服务器端还是在客户端都会进行有效性检查。如果是,那就是 Tyrus 的 bug。
WebSocketListener
of nv-websocket-client有onFrame
、onTextFrame
、onContinuationFrame
等帧粒度的回调方法(注意onTextMessage
和onTextFrame
不同),因此您可以在那里检查每个帧的字节数组。
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 连接中发生的情况?
我刚刚遇到了同样的错误。在我从 org.glassfish.tyrus
版本 1.1 更改为 2.0.0 后,它没有任何问题。