Answers inline ..
On Wed, Aug 21, 2013 at 4:28 AM, Kasper Nielsen <[email protected]> wrote:
> Hi,
>
> A couple of questions about the WebSocketListener interface, which is not
> completely clear by reading the Javadoc.
>
> 1) Concurrent invokes
> Methods are always invoked one at a time?
> So, for example, onWebSocketError() is never concurrently invoked with
> onWebSocketText().
>
In general, yes, this is true.
However, there are scenarios where this might be perceived as false.
Example:
Jetty calls onWebSocketText(String), and as you are processing it, you
allow an unhandled exception to flow out of your code.
This is caught by Jetty, and a websocket close is issued to the remote side.
Which also results in onWebSocketError(Throwable) being called for the
unhandled exception.
And a onWebSocketClose(int, String) being called for the abnormal close.
>
> 2)
> onWebSocketClose and onWebSocketError are never both invoked at the end of
> the lifecycle of a listener. If onWebSocketError is invoked,
> onWebSocketClose is never invoked, right?
>
This is possibly.
You should always receive a onWebSocketClose.
And if the cause of the close was due to abnormal behavior on your
WebSocket side (such as an uncaught exception, or protocol error) then you
will receive a onWebSocketError as well.
It is also possible for you to initiate a Session.close(), triggering the
close handshake, get a OnWebSocketError(Throwable) indicating that the
connection isn't alive (think SocketError, IOException, EOFException,
etc...) and then a local abnormal close on onWebSocketClose(int, String)
>
> 3)
> The first method invoked is always onWebSocketConnect?
> For example, onWebSocketError is never invoked as the first operation?
>
In general, Yes, onWebSocketConnect() is the first method called.
Even if you have a connection issue, the behavior would be as follows.
Server Socket: If the handshake or connect doesn't work, the more
fundamental upgrade mechanism will respond via the HTTP response mechanism
the error situation.
Never notifying the socket implementation of the connect attempt or error.
Client Socket: If you have a problem connecting, or during the handshake,
you'll get that exception back via the Future on the
WebSocketClient.connect() call.
However, it is possible with annotated WebSockets to have this appear to be
false.
Example: Your annotated websockets has itself declared like this ...
public class MySocket {
public void onConnect(Session session) {
}
@OnWebSocketError
public void onError(Throwable t) {
}
}
Obviously, the unannotated onConnect isn't going to be called.
>
>
> 4)
> So the lifecycle of a WebSocketListener is roughly as follows:
>
> onWebSocketConnect() -> followed by
> 0 or more onWebSocketBinary() or onWebSocketText() (sequentiel) ->
> followed by
> onWebSocketError or onWebSocketClose -> no listener methods is invoked
> after this.
>
It is possible to receive more than 1 onWebSocketError().
Even after the onWebSocketClose().
Example:
You are using the streaming API from a thread of your own to write a big
message to the Remote endpoint, lets say via the Jetty 9.1
RemoteEndpoint.getWriter() mechanism.
The remote responds to your message with a sudden close code 1009
(Message too large)
Internally, the implementation is queuing and fragmenting the various
parts of your message to be sent when it can.
You'll get a onWebSocketClose() with the details from the remote
endpoint's 1009 close, then shortly afterwords your thread will get an
exception on the next write attempt.
Your socket will be notified of the failure to write in
onWebSocketError() too.
All pending frames in the queue that are unwritten will have their
callbacks / futures failed as well (this is an async operation).
If your thread decides to cleanup in a catch block and issue a
Session.close(), you might get an IOException during that call (dependent
on threading behavior) , but you'll get another onWebSocketError()
indicating the failure to issue a close. (as the socket is already closed).
Example 2:
You are using extensions, such as the deflate extension.
Something in the extension is unhappy and throws an exception.
This will trigger the websocket implementation to close the connection.
This could result in onWebSocketError() from the extension, and for
actions that extension was trying to handle.
You could see in your socket a onWebSocketError() from the extension, a
onWebSocketClose() from the implementation, and another onWebSocketError()
from your own pending actions that failed during processing deep in the
bowels of the implementation.
>
> Cheers
> Kasper
>
>
- Joakim
_______________________________________________
jetty-users mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/jetty-users