tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Konstantin Preißer <>
Subject Some Websocket (Async) questions
Date Wed, 23 Oct 2013 00:09:18 GMT
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:

        public void onMessage(String message, boolean last) {

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.


Konstantin Preißer

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message