如何处理 websocket @OnError
How to handle websocket @OnError
除了记录错误之外,处理 websocket 错误的正确方法是什么?
关于 onError()
,端点 documentation 指出:
Developers may implement this method when the web socket session
creates some kind of error that is not modeled in the web socket
protocol. This may for example be a notification that an incoming
message is too big to handle, or that the incoming message could not
be encoded.
There are a number of categories of exception that this method is
(currently) defined to handle:
connection problems, for example, a socket failure that occurs before the web socket connection can be formally closed. These are modeled as SessionExceptions
runtime errors thrown by developer created message handlers calls.
conversion errors encoding incoming messages before any message handler has been called. These are modeled as DecodeExceptions
是否所有这些类型的异常都是致命的,导致 websocket 关闭?
如果发生错误onError()
方法是否应该关闭websocket(调用Session.close()
)?
到目前为止,我认为我有责任彻底关闭会话,并告知客户关闭原因。这就是为什么我的 onError()
尝试在 session.isOpen()
返回 true 时调用 session.close()
,但这导致 tomcat (8.0.15) 抛出 NullPointerException
:
...
Caused by: java.lang.NullPointerException
at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.onWritePossible(WsRemoteEndpointImplServer.java:96)
at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:81)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:444)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessage(WsRemoteEndpointImplBase.java:335)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:264)
at org.apache.tomcat.websocket.WsSession.sendCloseMessage(WsSession.java:536)
at org.apache.tomcat.websocket.WsSession.doClose(WsSession.java:464)
at org.apache.tomcat.websocket.WsSession.close(WsSession.java:441)
at my.package.MyEndpoint.onWebSocketError(MyEndpoint.java:229)
... 18 more
这是 tomcat 错误、我的误解,还是两者兼而有之?
编辑: Java EE websocket 示例 dukeeetf2 似乎假定错误是致命的;并且无需关闭会话。记录错误,并删除会话:
@OnError
public void error(Session session, Throwable t) {
/* Remove this connection from the queue */
queue.remove(session);
logger.log(Level.INFO, t.toString());
logger.log(Level.INFO, "Connection error.");
}
@OnError
方法调用并不意味着Session会被关闭;你可以做任何你想做的,这取决于你的应用程序指定的合同。
tomcat 实现的堆栈跟踪似乎是一个错误。
ad dukeeetf2 示例 - 似乎此代码包含其他假设 - 端点不会引发异常,因此此处捕获的所有内容都来自底层 WebSocket 框架实现。这并不意味着有 "Connection Error";我可能会立即关闭(如果这是我不希望我的应用程序处理错误的方式);此实现可能会导致在没有任何消息的情况下打开连接。
我看到这有点过时,但今天在寻找此信息时最终来到这里。
根据您对 websocket 状态的依赖程度,您需要手动关闭会话,至少对于 javax.websocket 实施。
在我的例子中,发生的错误导致了网络会话客户端管理实现的问题,所以我像上面的例子一样关闭了会话。
我认为这取决于你需要什么,但它在这个实现中肯定不会关闭会话。
除了记录错误之外,处理 websocket 错误的正确方法是什么?
关于 onError()
,端点 documentation 指出:
Developers may implement this method when the web socket session creates some kind of error that is not modeled in the web socket protocol. This may for example be a notification that an incoming message is too big to handle, or that the incoming message could not be encoded.
There are a number of categories of exception that this method is (currently) defined to handle:
connection problems, for example, a socket failure that occurs before the web socket connection can be formally closed. These are modeled as SessionExceptions
runtime errors thrown by developer created message handlers calls.
conversion errors encoding incoming messages before any message handler has been called. These are modeled as DecodeExceptions
是否所有这些类型的异常都是致命的,导致 websocket 关闭?
如果发生错误onError()
方法是否应该关闭websocket(调用Session.close()
)?
到目前为止,我认为我有责任彻底关闭会话,并告知客户关闭原因。这就是为什么我的 onError()
尝试在 session.isOpen()
返回 true 时调用 session.close()
,但这导致 tomcat (8.0.15) 抛出 NullPointerException
:
...
Caused by: java.lang.NullPointerException
at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.onWritePossible(WsRemoteEndpointImplServer.java:96)
at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:81)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:444)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessage(WsRemoteEndpointImplBase.java:335)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:264)
at org.apache.tomcat.websocket.WsSession.sendCloseMessage(WsSession.java:536)
at org.apache.tomcat.websocket.WsSession.doClose(WsSession.java:464)
at org.apache.tomcat.websocket.WsSession.close(WsSession.java:441)
at my.package.MyEndpoint.onWebSocketError(MyEndpoint.java:229)
... 18 more
这是 tomcat 错误、我的误解,还是两者兼而有之?
编辑: Java EE websocket 示例 dukeeetf2 似乎假定错误是致命的;并且无需关闭会话。记录错误,并删除会话:
@OnError
public void error(Session session, Throwable t) {
/* Remove this connection from the queue */
queue.remove(session);
logger.log(Level.INFO, t.toString());
logger.log(Level.INFO, "Connection error.");
}
@OnError
方法调用并不意味着Session会被关闭;你可以做任何你想做的,这取决于你的应用程序指定的合同。
tomcat 实现的堆栈跟踪似乎是一个错误。
ad dukeeetf2 示例 - 似乎此代码包含其他假设 - 端点不会引发异常,因此此处捕获的所有内容都来自底层 WebSocket 框架实现。这并不意味着有 "Connection Error";我可能会立即关闭(如果这是我不希望我的应用程序处理错误的方式);此实现可能会导致在没有任何消息的情况下打开连接。
我看到这有点过时,但今天在寻找此信息时最终来到这里。 根据您对 websocket 状态的依赖程度,您需要手动关闭会话,至少对于 javax.websocket 实施。
在我的例子中,发生的错误导致了网络会话客户端管理实现的问题,所以我像上面的例子一样关闭了会话。 我认为这取决于你需要什么,但它在这个实现中肯定不会关闭会话。