简体   繁体   English

如何处理 websocket @OnError

[英]How to handle websocket @OnError

What's the correct way of handling a websocket error besides logging it?除了记录它之外,处理 websocket 错误的正确方法是什么?

Regarding onError() , the Endpoint documentation states that:关于onError() ,端点文档指出:

Developers may implement this method when the web socket session creates some kind of error that is not modeled in the web socket protocol.当 Web 套接字会话创建某种未在 Web 套接字协议中建模的错误时,开发人员可以实现此方法。 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.连接问题,例如,在 Web 套接字连接可以正式关闭之前发生的套接字故障。 These are modeled as SessionExceptions这些被建模为 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这些被建模为 DecodeExceptions

Are all of these types of exceptions fatal, causing the websocket to close?所有这些类型的异常都是致命的,导致 websocket 关闭吗?

Should the onError() method close the websocket (call Session.close() ) if an error occurs?如果发生错误, onError()方法是否应该关闭 websocket(调用Session.close() )?

So far, I assumed that it's my responsibility to cleanly close the session, informing the client about the close reason.到目前为止,我认为干净地关闭会话是我的责任,将关闭原因告知客户。 This is why my onError() tried invoking session.close() if session.isOpen() returned true, but this caused tomcat (8.0.15) to throw a NullPointerException :这就是为什么我的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

Is this a tomcat bug, a misunderstanding on my part, or both?这是一个tomcat错误,是我的误解,还是两者兼而有之?

Edit: It seems that the Java EE websocket example dukeeetf2 assumes that errors are fatal;编辑:似乎 Java EE websocket 示例dukeeetf2假定错误是致命的; and that there's no need to close the session.并且不需要关闭会话。 The errors are logged, and the session is removed:记录错误,并删除会话:

@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 method invocation does not mean that Session will be closed; @OnError方法调用并不意味着 Session 将被关闭; You can do whatever you want, it depends in the contract specified by your application.您可以为所欲为,这取决于您的应用程序指定的合同。

stacktrace from tomcat implementation seems like a bug.来自 tomcat 实现的堆栈跟踪似乎是一个错误。

ad dukeeetf2 sample - seems like this code contains other assumptions - Endpoints does not throw an exception, so everything caught here is from underlying WebSocket framework implementation. ad dukeeetf2示例 - 似乎此代码包含其他假设 - Endpoints 不会引发异常,因此此处捕获的所有内容都来自底层 WebSocket 框架实现。 That does not really mean that there is an "Connection Error";这并不意味着存在“连接错误”; I would maybe do close right away (if this is how I wan't my application to handle errors);我可能会立即关闭(如果这是我的应用程序处理错误的方式); this implementation could result in opened connections without any messages.此实现可能导致打开的连接没有任何消息。

I saw this is a bit dated but ended up here today when looking for this info.我看到这有点过时,但今天在寻找此信息时最终来到这里。 Depending on how you rely on the state of the websocket, you need to close the session manually, at least for the javax.websocket implementation.根据您对 websocket 状态的依赖程度,您需要手动关闭会话,至少对于 javax.websocket 实现而言。

In my case, the error happening was causing a problem for the websession client administration implementation, so I closed the session as in the above example.就我而言,发生的错误导致 websession 客户端管理实现出现问题,因此我如上例所示关闭了会话。 I think it depends on what you need, but it certainly does not do a close session in this implementation.我认为这取决于您需要什么,但它肯定不会在此实现中进行关闭会话。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM