public interface WebSocket
WebSocket connection is a full-duplex communication over TCP, used to exchange text and binary data, also providing a number of keep-alive features.
Once a WebSocket is available, it's connected and is ready to send and
receive messages. Messages can be sent and received up until the WebSocket
is closed. Once it's closed it remains so forever (i.e. cannot be
reopened).
A WebSocket
is created by a builder
.
The builder is used to configure the desired properties of the WebSocket
, an initial handshake, and to assign handlers for incoming data
and lifecycle events.
Since WebSocket is a full-duplex protocol, incoming and outgoing destinations are independent from each other. This API permits operations in different directions to proceed simultaneously.
Messages are sent asynchronously. In other words each method only initiates a corresponding operation, but the outcome is communicated through completion handler supplied to the method rather than by the method itself.
In contrast to the above, received messages are pushed (delivered) to
notification handlers assigned during the building of the WebSocket
.
To provide a compliance with reactive stream processing, a "reactive pull"
model is used. That is, a message is pushed to a handler if there's a message
the server might send to the client and the client is ready to receive
at least one more message. This client deemed ready to receive a message if
there's an unsatisfied demand previously signalled by request(long)
.
When the WebSocket
is no longer needed it should be closed. It
could be done either of two ways. To close orderly, the client must engage in
a closing handshake. The closing handshake deemed completed and a WebSocket
is closed when client has both sent
and received
a Close message. To close
promptly, the client should call abort()
.
The WebSocket Protocol specifies 5 types of messages: Text, Binary, Ping, Pong and Close. Text and Binary messages are used to exchange data. Ping and Pong for keep-alive support. A Close message is for closing the connection.
A payload, a message of each type can carry, differs in semantics and
structure. Text and Binary messages can carry data of an arbitrary length.
The only difference is that the contents of a Text message has to be a valid
UTF-8 sequence. Ping and Pong can contain up to 125 bytes of any data. A
Close message can be of 3 types: an empty one, with a closure status code or
with a closure status code and up to 123 bytes of valid UTF-8 sequence that
represents a reason for closure.
In addition to this, Both Text and Binary messages can be split into
ordered sequences of chunks (incomplete messages) and send and delivered one
by one to an endpoint. Both delivering and sending of message of those types
provide a boolean flag isLast
to mark boundaries between sequences.
The simplest sequence in that model would be a single incomplete message with
isLast == true
, that represent a single unsplit message.
Sequences are not permitted to interleave. That is,
it's not allowed to start a new sequence of incomplete Text or Binary
messages, not having finished the previous one.
The WebSocket
provides a "send-method" per each of the types above,
plus several convenience methods for Text and Binary types.
The builder provides a way to assign a separate notification handler for
every of the types above. The handler is called each time a message of a
corresponding type has been received.
Every method that sends a message takes the message's payload and a
completion handler
parametrized by Throwable
. When
the operation started by the method finishes, the handler is called. If the
operation finished normally, the handler is called with null
.
Otherwise, actual exception is provided.
Some of the methods take an arbitrary context object a user may want to
provide. In this case the method takes a handler
parametrized by both type of the context and Throwable
. Later the
handler is called with the captured context. This may be useful, for example
to, distinguish between different operations that are serviced by the same
handler.
In every case when called, handlers also provide a WebSocket
the
operation has been initiated upon.
If a payload provided to a method in the form of ByteBuffer
, then
the payload deemed to start at buffer's position and end at buffer's Buffer.limit().
A completion handler will be called only after sending all the payload
provided (or before that in the case of an error).
The implementation guarantees not to retain any references to the payload
after the handler is called, so those payload carrying objects can be reused.
One outstanding operation that sends a message is permitted. If another
send operation is initiated before the previous one has completed, an IllegalStateException
will be thrown to the caller
(not passed to the operation's handler).
If any violations of message integrity (size, type, etc.) are detected
in an outgoing message, an IllegalArgumentException
is reported to
the completion handler of the corresponding operation.
If an interleaving of sequences is detected while sending a message, an
IllegalStateException
is reported to the completion handler of the
corresponding operation.
The builder provides methods for assigning handlers for messages of
each type. Once a WebSocket
is available an assigned handler is
continuously called each time a message of a corresponding type has been
received. Assigned handlers are called in a strict sequential order, one
after another, though may be by different threads.
The implementation may reuse payload carrying objects passed to a handler, thus users must not retain any references to these data structures longer than the duration of call. If more lifetime needed, a copy should be made.
When the implementation receives a message of type a handler hasn't been assigned for, the behaviour is the same as if the handler was:
webSocket.request(1)
In other words, the message is ignored, and one more message is requested.
If any violations of message integrity (size, type, etc.) are detected
in an incoming message, an IllegalArgumentException
is reported to
the error handler.
If an interleaving of sequences is detected while receiving a message, an
IllegalStateException
is reported to the error handler.
error handler
.
Unless otherwise noted, passing a null
argument to a
constructor or method of this type (or any inner one) will cause a NullPointerException
to be thrown immediately to the
caller.
Modifier and Type | Interface and Description |
---|---|
static interface |
WebSocket.BiHandler<T,U>
2-parameter callback used by
WebSocket . |
static class |
WebSocket.Builder
A builder for creating
WebSocket instances. |
static interface |
WebSocket.Handler<T>
1-parameter callback used by
WebSocket . |
static class |
WebSocket.StatusCode
WebSocket Protocol closure status code.
|
Modifier and Type | Method and Description |
---|---|
void |
abort()
Forces the
WebSocket to close promptly. |
java.lang.String |
getSubprotocol()
Returns a subprotocol
effective for this
WebSocket . |
boolean |
isClosed()
Tells whether this
WebSocket is closed. |
<C> void |
ping(java.nio.ByteBuffer payload,
C context,
WebSocket.BiHandler<? super C,? super java.lang.Throwable> completionHandler)
Sends a Ping message.
|
<C> void |
pong(java.nio.ByteBuffer payload,
C context,
WebSocket.BiHandler<? super C,? super java.lang.Throwable> completionHandler)
Sends a Pong message.
|
void |
request(long n)
Adds the given number of message deliveries to the current unfulfilled
demand.
|
void |
sendBinary(byte[] payload,
WebSocket.Handler<? super java.lang.Throwable> completionHandler)
Sends a Binary message with payload from the given byte array.
|
<C> void |
sendBinary(java.nio.ByteBuffer payload,
boolean isLast,
C context,
WebSocket.BiHandler<? super C,? super java.lang.Throwable> completionHandler)
Sends a, possibly incomplete, Binary message with payload from the
given
ByteBuffer . |
void |
sendBinary(java.io.InputStream payload,
WebSocket.Handler<? super java.lang.Throwable> completionHandler)
Sends a Binary message with payload from the given
InputStream . |
<C> void |
sendClose(WebSocket.StatusCode code,
java.lang.CharSequence reason,
C context,
WebSocket.BiHandler<? super C,? super java.lang.Throwable> completionHandler)
Sends a Close message with the given status code and the reason.
|
<C> void |
sendText(java.lang.CharSequence payload,
boolean isLast,
C context,
WebSocket.BiHandler<? super C,? super java.lang.Throwable> completionHandler)
Sends a possibly partial Text message consisting of the given character
sequence.
|
void |
sendText(java.lang.CharSequence payload,
WebSocket.BiHandler<? super WebSocket,? super java.lang.Throwable> completionHandler)
Sends a Text message consisting of the given character sequence.
|
void |
sendText(java.lang.Iterable<? extends java.lang.CharSequence> payload,
WebSocket.BiHandler<? super WebSocket,? super java.lang.Throwable> completionHandler)
Sends a Text message consisting of concatenation of character sequences
provided by the given
Iterable . |
<C> void sendText(java.lang.CharSequence payload, boolean isLast, C context, WebSocket.BiHandler<? super C,? super java.lang.Throwable> completionHandler)
An exception will be reported to the provided completionHandler
in the following cases:
IllegalArgumentException
if the payload
is not
UTF-8 encodable
IllegalStateException
if interleaving is detected
AsyncCloseException
if the WebSocket
closes while
this operation is in progress
IOException
if an I/O error occurs during this operation
C
- the type of the contextpayload
- the payloadisLast
- true
if this message is the last in the
current sequence of Text messages,
false
otherwisecontext
- the context of this operation;
can be null
completionHandler
- the completion handlerjava.lang.IllegalStateException
- if the WebSocket is closedjava.lang.NullPointerException
- if any of the arguments except the context
are nullvoid sendText(java.lang.CharSequence payload, WebSocket.BiHandler<? super WebSocket,? super java.lang.Throwable> completionHandler)
This is a convenience method. For the most general case use sendText(CharSequence, boolean, Object, BiHandler)
.
payload
- the payloadcompletionHandler
- the completion handlerjava.lang.IllegalStateException
- if the WebSocket is closedjava.lang.NullPointerException
- if any of the arguments are nullvoid sendText(java.lang.Iterable<? extends java.lang.CharSequence> payload, WebSocket.BiHandler<? super WebSocket,? super java.lang.Throwable> completionHandler)
Iterable
.
This is a convenience method. For the most general case use sendText(CharSequence, boolean, Object, BiHandler)
.
payload
- the payloadcompletionHandler
- the completion handlerjava.lang.IllegalStateException
- if the WebSocket is closedjava.lang.NullPointerException
- if any of the arguments are null<C> void sendBinary(java.nio.ByteBuffer payload, boolean isLast, C context, WebSocket.BiHandler<? super C,? super java.lang.Throwable> completionHandler)
ByteBuffer
.
The bytes are taken from the given ByteBuffer
's position to
its limit.
An exception will be reported to the provided completionHandler
in the following cases:
IllegalStateException
if interleaving is detected
AsyncCloseException
if the WebSocket
closes while
this operation is in progress
IOException
if an I/O error occurs during this operation
C
- the type of the contextpayload
- the payloadisLast
- true
if this message is the last in the
current sequence of Binary messages,
false
otherwisecontext
- the context of this operation;
can be null
completionHandler
- the completion handlerjava.lang.IllegalStateException
- if the WebSocket is closedjava.lang.NullPointerException
- if any of the arguments except the context
are nullvoid sendBinary(java.io.InputStream payload, WebSocket.Handler<? super java.lang.Throwable> completionHandler)
InputStream
.
This is a convenience method. For the most general case use sendBinary(ByteBuffer, boolean, Object, BiHandler)
.
payload
- the payloadcompletionHandler
- the completion handlerjava.lang.IllegalStateException
- if the WebSocket is closedjava.lang.NullPointerException
- if any of the arguments are nullvoid sendBinary(byte[] payload, WebSocket.Handler<? super java.lang.Throwable> completionHandler)
This is a convenience method. For the most general case use sendBinary(ByteBuffer, boolean, Object, BiHandler)
.
payload
- the payloadcompletionHandler
- the completion handlerjava.lang.IllegalStateException
- if the WebSocket is closedjava.lang.NullPointerException
- if any of the arguments are null<C> void ping(java.nio.ByteBuffer payload, C context, WebSocket.BiHandler<? super C,? super java.lang.Throwable> completionHandler)
An exception will be reported to the provided completionHandler
in the following cases:
IllegalArgumentException
if the payload.remaining >
125
AsyncCloseException
if the WebSocket
closes while
this operation is in progress
IOException
if an I/O error occurs during this operation
C
- the type of the contextpayload
- the payloadcontext
- the context of this operation;
can be null
completionHandler
- the completion handlerjava.lang.IllegalStateException
- if the WebSocket is closedjava.lang.NullPointerException
- if any of the arguments except the context
are null<C> void pong(java.nio.ByteBuffer payload, C context, WebSocket.BiHandler<? super C,? super java.lang.Throwable> completionHandler)
An exception will be reported to the provided completionHandler
in the following cases:
IllegalArgumentException
if the payload.remaining >
125
AsyncCloseException
if the WebSocket
closes while
this operation is in progress
IOException
if an I/O error occurs during this operation
C
- the type of the contextpayload
- the payloadcontext
- the context of this operation;
can be null
completionHandler
- the completion handlerjava.lang.IllegalStateException
- if the WebSocket is closedjava.lang.NullPointerException
- if any of the arguments except the context
are null<C> void sendClose(WebSocket.StatusCode code, java.lang.CharSequence reason, C context, WebSocket.BiHandler<? super C,? super java.lang.Throwable> completionHandler)
An exception will be reported to the provided completionHandler
in the following cases:
IllegalArgumentException
if the reason
is not
UTF-8 encodable or has a longer than 123
bytes UTF-8
representation
AsyncCloseException
if the WebSocket
closes while
this operation is in progress
IOException
if an I/O error occurs during this operation
C
- the type of the contextcode
- the status codereason
- the valid UTF-16 sequence, that has a no longer
than 123
bytes UTF-8 representation;
can be emptycontext
- the context of this operation;
can be null
completionHandler
- the completion handlerjava.lang.IllegalStateException
- if the WebSocket is closedjava.lang.NullPointerException
- if any of the arguments except the context
are nulljava.lang.String getSubprotocol()
WebSocket
.null
if there is nonevoid request(long n)
The WebSocket
will make n
more invocations of
assigned onText
, onBinary
, onPing
, onPong
and onClose
handlers (or less if either of the
endpoints decide to close the connection before that).
java.lang.IllegalArgumentException
- if n < 0
boolean isClosed()
WebSocket
is closed.
A WebSocket
deemed closed when either the underlying socket
is closed or the closing handshake is completed.
true
if the WebSocket
is closed,
false
otherwisevoid abort() throws java.io.IOException
WebSocket
to close promptly.
This method closes the underlying TCP connection. If the WebSocket
is already closed then invoking this method has no effect.
java.io.IOException
- if an I/O error occurs