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

Reply via email to