Hi all, while working on the Drawboard Websocket example that is included in Tomcat, I found some things in Tomcat's implementation / the Websocket Spec which I'm not clear about.
1) How to asynchronously close / abort a Websocket session? For the Drawboard, I'm using the RemoteEndpoint.Async to send messages asynchronously (that is, the sendText(String, SendHandler) will return immediately and when sending is finished, SendHandler.onResult() will be called). Now, there may be a situation where I want to abort a Websocket session while async send has not yet finished, or asynchronously close it so that a close() method does not block. The only way to close a websocket normally (not aborting) seems to be by calling Session.close(). However, this method will block if the remote endpoint does not read data, and it seems there is no async close() method that returns immediately (just like Async.sendText()) even if the closing handshake is waiting to be sent on the TCP connection. The problem with the Drawboard example is that it needs to be able to abort/close Websocket sessions if the client does not read data from the TCP connection, to avoid buffering outgoing messages endlessly. Currently, I'm just calling session.close() (while async sending has not yet finished), but as this method may block, it temporarily stops processing of messages from other clients. (For example, in .Net there is a CloseAsync()/CloseOutputAsync method of the WebSocket class that asynchronously sends the closing handshake, and an Abort() method that immediately aborts the Websocket/TCP connection and cancels all pending I/O operations. Ideally, I would need something like this Abort() method for immediately aborting the Websocket session). 2) It seems that when using RemoteEndpoint.Basic to send data synchronously and the remote endpoint does not read from the TCP connection, then a TimeoutException (wrapped in IOException) is thrown several seconds after calling send(). However, when using RemoteEndpoint.Async to send data asynchronously, this is not the case - the SendHandler is not called until the remote endpoint continues to read data. Is there some configuration to set a Timeout for async sending? 3) It seems that session.close() will call the onClose method of the Endpoint, even if this was called inside of another event handling method like onMessage. E.g. if you do something like this in an Endpoint subclass: @Override public void onMessage(String message, boolean last) { session.close(); } then Endpoint.onClose(..) will be called directly from session.close() (it will be called before onMessage(...) returns). This can be a bit confusing, because e.g. in Javascript, if you call ws.close() inside of the onmessage handler, then the onclose handler will be called after the onmessage handler returns. Is this behavior required by the spec? (E.g. JSR 356 spec says at point 4.5 @OnClose: "The annotation defines that the decorated method be called whenever a remote peer is about to be disconnected from this endpoint, whether that process is initiated by the remote peer, by the local container or by a call to session.close(). The container notifies the method before the connection is brought down [WSC-4.5-1]." If the last sentence is to be interpreted that the Websocket closing handshake must not be sent until onClose() was called, this would explain it, although that would seem a bit strange to me. Thanks! Regards, Konstantin Preißer --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org