/*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.incubator.http;
import java.io.IOException;
import java.net.ProtocolException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
A WebSocket client conforming to RFC 6455.
{@Incubating}
A WebSocket
provides full-duplex communication over a TCP connection.
To create a WebSocket
use a builder. Once a WebSocket
is built, it's ready to send and receive messages. When the WebSocket
is no longer needed it must be closed: a Close message must both be
sent and received. The WebSocket
may be also closed abruptly.
Once closed the WebSocket
remains closed and cannot be reopened.
Messages of type X
(where X
is one of: Text, Binary, Ping, Pong or Close) are sent and received asynchronously through the
WebSocket.send{X}
and Listener
.on{X}
methods respectively. Each method returns a CompletionStage
which completes when the operation has completed.
Note that messages (of any type) are received only if requested.
One outstanding send operation is permitted. No further send operation can be initiated before the previous one has completed. When sending, a message must not be modified until the returned CompletableFuture
completes (either normally or exceptionally).
Text and Binary messages can be sent and received as a whole or in parts.
A whole message is transferred as a sequence of one or more invocations of a
corresponding method where the last invocation is identified via an
additional method argument.
If the message is contained in a ByteBuffer
, bytes are considered arranged from the buffer
's position
to the buffer
's limit
.
Unless otherwise stated, null
parameter values will cause methods and constructors to throw NullPointerException
.
Implementation Note: This implementation's methods do not block before returning a CompletableFuture
. Since: 9
/**
* A WebSocket client conforming to RFC 6455.
* {@Incubating}
*
* <p> A {@code WebSocket} provides full-duplex communication over a TCP
* connection.
*
* <p> To create a {@code WebSocket} use a {@linkplain HttpClient#newWebSocketBuilder(
* URI, Listener) builder}. Once a {@code WebSocket} is built, it's ready
* to send and receive messages. When the {@code WebSocket} is no longer needed
* it must be closed: a Close message must both be {@linkplain #sendClose
* sent} and {@linkplain Listener#onClose(WebSocket, int, String) received}.
* The {@code WebSocket} may be also closed {@linkplain #abort() abruptly}.
*
* <p> Once closed the {@code WebSocket} remains {@linkplain #isClosed() closed}
* and cannot be reopened.
*
* <p> Messages of type {@code X} (where {@code X} is one of: Text, Binary,
* Ping, Pong or Close) are sent and received asynchronously through the {@code
* WebSocket.send{X}} and {@link WebSocket.Listener}{@code .on{X}} methods
* respectively. Each method returns a {@link CompletionStage} which completes
* when the operation has completed.
*
* <p> Note that messages (of any type) are received only if {@linkplain
* #request(long) requested}.
*
* <p> One outstanding send operation is permitted. No further send operation
* can be initiated before the previous one has completed. When sending, a
* message must not be modified until the returned {@link CompletableFuture}
* completes (either normally or exceptionally).
*
* <p> Text and Binary messages can be sent and received as a whole or in parts.
* A whole message is transferred as a sequence of one or more invocations of a
* corresponding method where the last invocation is identified via an
* additional method argument.
*
* <p> If the message is contained in a {@link ByteBuffer}, bytes are considered
* arranged from the {@code buffer}'s {@link ByteBuffer#position() position} to
* the {@code buffer}'s {@link ByteBuffer#limit() limit}.
*
* <p> Unless otherwise stated, {@code null} parameter values will cause methods
* and constructors to throw {@link NullPointerException}.
*
* @implNote This implementation's methods do not block before returning
* a {@code CompletableFuture}.
*
* @since 9
*/
public interface WebSocket {
The WebSocket Close message status code (1000
),
indicating normal closure, meaning that the purpose for which the
connection was established has been fulfilled.
See Also:
/**
* The WebSocket Close message status code (<code>{@value}</code>),
* indicating normal closure, meaning that the purpose for which the
* connection was established has been fulfilled.
*
* @see #sendClose(int, String)
* @see Listener#onClose(WebSocket, int, String)
*/
int NORMAL_CLOSURE = 1000;
A builder for creating WebSocket
instances. {@Incubating} To build a WebSocket
, create a builder, configure it as required by calling intermediate methods (the ones that return the builder itself), then finally call buildAsync()
to get a CompletableFuture
with resulting WebSocket
.
If an intermediate method has not been called, an appropriate
default value (or behavior) will be used. Unless otherwise noted, a
repeated call to an intermediate method overwrites the previous value (or
overrides the previous behaviour).
Instances of Builder
are not safe for use by multiple threads without external synchronization.
Since: 9
/**
* A builder for creating {@code WebSocket} instances.
* {@Incubating}
*
* <p> To build a {@code WebSocket}, {@linkplain HttpClient#newWebSocketBuilder(
* URI, Listener) create} a builder, configure it as required by
* calling intermediate methods (the ones that return the builder itself),
* then finally call {@link #buildAsync()} to get a {@link
* CompletableFuture} with resulting {@code WebSocket}.
*
* <p> If an intermediate method has not been called, an appropriate
* default value (or behavior) will be used. Unless otherwise noted, a
* repeated call to an intermediate method overwrites the previous value (or
* overrides the previous behaviour).
*
* <p> Instances of {@code Builder} are not safe for use by multiple threads
* without external synchronization.
*
* @since 9
*/
interface Builder {
Adds the given name-value pair to the list of additional headers for
the opening handshake.
Headers defined in WebSocket Protocol are not allowed to be added.
Params: - name –
the header name
- value –
the header value
Returns: this builder
/**
* Adds the given name-value pair to the list of additional headers for
* the opening handshake.
*
* <p> Headers defined in WebSocket Protocol are not allowed to be added.
*
* @param name
* the header name
* @param value
* the header value
*
* @return this builder
*/
Builder header(String name, String value);
Includes a request for the given subprotocols during the opening
handshake.
Among the requested subprotocols at most one will be chosen by the server. This subprotocol will be available from WebSocket.getSubprotocol
. Subprotocols are specified in the order of preference.
Each of the given subprotocols must conform to the relevant
rules defined in the WebSocket Protocol.
If this method is not invoked then no subprotocols are requested.
Params: - mostPreferred –
the most preferred subprotocol
- lesserPreferred –
the lesser preferred subprotocols, with the least preferred
at the end
Returns: this builder
/**
* Includes a request for the given subprotocols during the opening
* handshake.
*
* <p> Among the requested subprotocols at most one will be chosen by
* the server. This subprotocol will be available from {@link
* WebSocket#getSubprotocol}. Subprotocols are specified in the order of
* preference.
*
* <p> Each of the given subprotocols must conform to the relevant
* rules defined in the WebSocket Protocol.
*
* <p> If this method is not invoked then no subprotocols are requested.
*
* @param mostPreferred
* the most preferred subprotocol
* @param lesserPreferred
* the lesser preferred subprotocols, with the least preferred
* at the end
*
* @return this builder
*/
Builder subprotocols(String mostPreferred, String... lesserPreferred);
Sets a timeout for the opening handshake.
If the opening handshake does not complete within the specified duration then the CompletableFuture
returned from buildAsync()
completes exceptionally with a HttpTimeoutException
.
If this method is not invoked then the timeout is deemed infinite.
Params: Returns: this builder
/**
* Sets a timeout for the opening handshake.
*
* <p> If the opening handshake does not complete within the specified
* duration then the {@code CompletableFuture} returned from {@link
* #buildAsync()} completes exceptionally with a {@link
* HttpTimeoutException}.
*
* <p> If this method is not invoked then the timeout is deemed infinite.
*
* @param timeout
* the timeout, non-{@linkplain Duration#isNegative() negative},
* non-{@linkplain Duration#ZERO ZERO}
*
* @return this builder
*/
Builder connectTimeout(Duration timeout);
Builds a WebSocket
. Returns a CompletableFuture<WebSocket>
which completes normally with the WebSocket
when it is connected or completes exceptionally if an error occurs.
CompletableFuture
may complete exceptionally with the following errors:
-
IOException
- if an I/O error occurs -
WebSocketHandshakeException
- if the opening handshake fails -
HttpTimeoutException
- if the opening handshake does not complete within the specified duration -
InterruptedException
- if the operation was interrupted -
SecurityException
- if a security manager is set, and the caller does not have a URLPermission
for the WebSocket URI -
IllegalArgumentException
- if any of the additional
headers
are illegal; or if any of the WebSocket Protocol rules relevant to subprotocols
are violated; or if the connect timeout
is invalid;
Returns: a CompletableFuture
with the WebSocket
/**
* Builds a {@code WebSocket}.
*
* <p> Returns a {@code CompletableFuture<WebSocket>} which completes
* normally with the {@code WebSocket} when it is connected or completes
* exceptionally if an error occurs.
*
* <p> {@code CompletableFuture} may complete exceptionally with the
* following errors:
* <ul>
* <li> {@link IOException} -
* if an I/O error occurs
* <li> {@link WebSocketHandshakeException} -
* if the opening handshake fails
* <li> {@link HttpTimeoutException} -
* if the opening handshake does not complete within
* the specified {@linkplain #connectTimeout(Duration) duration}
* <li> {@link InterruptedException} -
* if the operation was interrupted
* <li> {@link SecurityException} -
* if a security manager is set, and the caller does not
* have a {@link java.net.URLPermission} for the WebSocket URI
* <li> {@link IllegalArgumentException} -
* if any of the additional {@link #header(String, String)
* headers} are illegal;
* or if any of the WebSocket Protocol rules relevant to {@link
* #subprotocols(String, String...) subprotocols} are violated;
* or if the {@link #connectTimeout(Duration) connect timeout}
* is invalid;
* </ul>
*
* @return a {@code CompletableFuture} with the {@code WebSocket}
*/
CompletableFuture<WebSocket> buildAsync();
}
A listener for events and messages on a WebSocket
. {@Incubating} Each method of Listener
corresponds to a type of event or a type of message. The WebSocket
argument of the method is the WebSocket
the event has occurred (the message has been received) on. All methods with the same WebSocket
argument are invoked in a sequential (and happens-before)
order, one after another, possibly by different threads.
-
onOpen
This method is invoked first.
-
onText
,
onBinary
, onPing
and onPong
These methods are invoked zero or more times after onOpen
. -
onClose
, onError
Only one of these methods is invoked, and that method is invoked last.
Messages received by the Listener
conform to the WebSocket Protocol, otherwise onError
with a ProtocolException
is invoked.
If a whole message is received, then the corresponding method (onText
or onBinary
) will be invoked with WHOLE
marker. Otherwise the method will be invoked with FIRST
, zero or more times with PART
and, finally, with LAST
markers. If any of the methods above throws an exception, onError
is then invoked with the same WebSocket
and this exception. Exceptions thrown from onError
or onClose
are ignored.
When the method returns, the message is deemed received (in particular, if contained in a ByteBuffer buffer
, the data is deemed received completely regardless of the result
buffer.hasRemaining()
upon the method's return. After this further messages may be received.
These invocations begin asynchronous processing which might not end with the invocation. To provide coordination, methods of Listener
return a CompletionStage
. The CompletionStage
signals the WebSocket
that the processing of a message has ended. For convenience, methods may return null
, which (by convention) means the same as returning an already completed (normally) CompletionStage
. If the returned CompletionStage
completes exceptionally, then onError
will be invoked with the same WebSocket
and this exception.
Control of the message passes to the Listener
with the invocation of the method. Control of the message returns to the
WebSocket
at the earliest of, either returning null
from the method, or the completion of the CompletionStage
returned from the method. The WebSocket
does not access the message while it's not in its control. The Listener
must not access the message after its control has been returned to the WebSocket
.
A WebSocket
implementation never invokes Listener
's methods with null
s as their arguments.
Since: 9
/**
* A listener for events and messages on a {@code WebSocket}.
* {@Incubating}
*
* <p> Each method of {@code Listener} corresponds to a type of event or a
* type of message. The {@code WebSocket} argument of the method is the
* {@code WebSocket} the event has occurred (the message has been received)
* on. All methods with the same {@code WebSocket} argument are invoked in a
* sequential
* (and <a href="../../../java/util/concurrent/package-summary.html#MemoryVisibility">happens-before</a>)
* order, one after another, possibly by different threads.
*
* <ul>
* <li> {@link #onOpen(WebSocket) onOpen} <br>
* This method is invoked first.
* <li> {@link #onText(WebSocket, CharSequence, WebSocket.MessagePart)
* onText}, {@link #onBinary(WebSocket, ByteBuffer, WebSocket.MessagePart)
* onBinary}, {@link #onPing(WebSocket, ByteBuffer) onPing} and {@link
* #onPong(WebSocket, ByteBuffer) onPong} <br>
* These methods are invoked zero or more times after {@code onOpen}.
* <li> {@link #onClose(WebSocket, int, String) onClose}, {@link
* #onError(WebSocket, Throwable) onError} <br>
* Only one of these methods is invoked, and that method is invoked last.
* </ul>
*
* <p> Messages received by the {@code Listener} conform to the WebSocket
* Protocol, otherwise {@code onError} with a {@link ProtocolException} is
* invoked.
*
* <p> If a whole message is received, then the corresponding method
* ({@code onText} or {@code onBinary}) will be invoked with {@link
* WebSocket.MessagePart#WHOLE WHOLE} marker. Otherwise the method will be
* invoked with {@link WebSocket.MessagePart#FIRST FIRST}, zero or more
* times with {@link WebSocket.MessagePart#PART PART} and, finally, with
* {@link WebSocket.MessagePart#LAST LAST} markers.
*
* If any of the methods above throws an exception, {@code onError} is then
* invoked with the same {@code WebSocket} and this exception. Exceptions
* thrown from {@code onError} or {@code onClose} are ignored.
*
* <p> When the method returns, the message is deemed received (in
* particular, if contained in a {@code ByteBuffer buffer}, the data is
* deemed received completely regardless of the result {@code
* buffer.hasRemaining()} upon the method's return. After this further
* messages may be received.
*
* <p> These invocations begin asynchronous processing which might not end
* with the invocation. To provide coordination, methods of {@code Listener}
* return a {@link CompletionStage CompletionStage}.
* The {@code CompletionStage} signals the {@code WebSocket} that the
* processing of a message has ended. For convenience, methods may return
* {@code null}, which (by convention) means the same as returning an
* already completed (normally) {@code CompletionStage}.
* If the returned {@code CompletionStage} completes exceptionally, then
* {@link #onError(WebSocket, Throwable) onError} will be invoked with the
* same {@code WebSocket} and this exception.
*
* <p> Control of the message passes to the {@code Listener} with the
* invocation of the method. Control of the message returns to the {@code
* WebSocket} at the earliest of, either returning {@code null} from the
* method, or the completion of the {@code CompletionStage} returned from
* the method. The {@code WebSocket} does not access the message while it's
* not in its control. The {@code Listener} must not access the message
* after its control has been returned to the {@code WebSocket}.
*
* <p> A {@code WebSocket} implementation never invokes {@code Listener}'s
* methods with {@code null}s as their arguments.
*
* @since 9
*/
interface Listener {
Notifies the Listener
that it is connected to the provided WebSocket
. The onOpen
method does not correspond to any message from the WebSocket Protocol. It is a synthetic event and the first
Listener
's method to be invoked.
This method is usually used to make an initial request for messages.
If an exception is thrown from this method then onError
will be invoked with the same WebSocket
and this exception.
Params: - webSocket –
the WebSocket
Implementation Requirements: The default implementation of this method behaves as if:
webSocket.request(1);
/**
* Notifies the {@code Listener} that it is connected to the provided
* {@code WebSocket}.
*
* <p> The {@code onOpen} method does not correspond to any message from
* the WebSocket Protocol. It is a synthetic event and the first {@code
* Listener}'s method to be invoked.
*
* <p> This method is usually used to make an initial {@linkplain
* WebSocket#request(long) request} for messages.
*
* <p> If an exception is thrown from this method then {@link
* #onError(WebSocket, Throwable) onError} will be invoked with the same
* {@code WebSocket} and this exception.
*
* @implSpec The default implementation of this method behaves as if:
*
* <pre>{@code
* webSocket.request(1);
* }</pre>
*
* @param webSocket
* the WebSocket
*/
default void onOpen(WebSocket webSocket) { webSocket.request(1); }
Receives a Text message.
The onText
method is invoked zero or more times between onOpen
and (onClose
or onError
).
This message may be a partial UTF-16 sequence. However, the
concatenation of all messages through the last will be a whole UTF-16
sequence.
If an exception is thrown from this method or the returned
CompletionStage
completes exceptionally, then onError
will be invoked with the same WebSocket
and this exception.
Params: - webSocket –
the WebSocket
- message –
the message
- part –
the part
Implementation Requirements: The default implementation of this method behaves as if:
webSocket.request(1);
return null;
Implementation Note: This implementation passes only complete UTF-16 sequences to the onText
method. Returns: a CompletionStage
which completes when the message processing is done; or null
if already done
/**
* Receives a Text message.
*
* <p> The {@code onText} method is invoked zero or more times between
* {@code onOpen} and ({@code onClose} or {@code onError}).
*
* <p> This message may be a partial UTF-16 sequence. However, the
* concatenation of all messages through the last will be a whole UTF-16
* sequence.
*
* <p> If an exception is thrown from this method or the returned {@code
* CompletionStage} completes exceptionally, then {@link
* #onError(WebSocket, Throwable) onError} will be invoked with the same
* {@code WebSocket} and this exception.
*
* @implSpec The default implementation of this method behaves as if:
*
* <pre>{@code
* webSocket.request(1);
* return null;
* }</pre>
*
* @implNote This implementation passes only complete UTF-16 sequences
* to the {@code onText} method.
*
* @param webSocket
* the WebSocket
* @param message
* the message
* @param part
* the part
*
* @return a {@code CompletionStage} which completes when the message
* processing is done; or {@code null} if already done
*/
default CompletionStage<?> onText(WebSocket webSocket,
CharSequence message,
MessagePart part) {
webSocket.request(1);
return null;
}
Receives a Binary message.
The onBinary
method is invoked zero or more times between onOpen
and (onClose
or onError
).
If an exception is thrown from this method or the returned
CompletionStage
completes exceptionally, then onError
will be invoked with the same WebSocket
and this exception.
Params: - webSocket –
the WebSocket
- message –
the message
- part –
the part
Implementation Requirements: The default implementation of this method behaves as if:
webSocket.request(1);
return null;
Returns: a CompletionStage
which completes when the message processing is done; or null
if already done
/**
* Receives a Binary message.
*
* <p> The {@code onBinary} method is invoked zero or more times
* between {@code onOpen} and ({@code onClose} or {@code onError}).
*
* <p> If an exception is thrown from this method or the returned {@code
* CompletionStage} completes exceptionally, then {@link
* #onError(WebSocket, Throwable) onError} will be invoked with the same
* {@code WebSocket} and this exception.
*
* @implSpec The default implementation of this method behaves as if:
*
* <pre>{@code
* webSocket.request(1);
* return null;
* }</pre>
*
* @param webSocket
* the WebSocket
* @param message
* the message
* @param part
* the part
*
* @return a {@code CompletionStage} which completes when the message
* processing is done; or {@code null} if already done
*/
default CompletionStage<?> onBinary(WebSocket webSocket,
ByteBuffer message,
MessagePart part) {
webSocket.request(1);
return null;
}
Receives a Ping message.
A Ping message may be sent or received by either client or
server. It may serve either as a keepalive or as a means to verify
that the remote endpoint is still responsive.
The WebSocket
handles Ping messages by replying with appropriate Pong messages using a strategy of its choice, but within the boundaries of the WebSocket Protocol. The WebSocket
may invoke onPing
after handling a Ping message, before doing so or in parallel with it. In other words no particular ordering is guaranteed. If an error occurs while implementation handles this Ping message, then onError
will be invoked with this error. For more details on handling Ping messages see RFC 6455 sections 5.5.2. Ping
and
5.5.3. Pong.
The message will consist of not more than 125
bytes: message.remaining() <= 125
.
The onPing
is invoked zero or more times in between onOpen
and (onClose
or onError
).
If an exception is thrown from this method or the returned
CompletionStage
completes exceptionally, then onError
will be invoked with this exception.
Params: - webSocket –
the WebSocket
- message –
the message
Implementation Requirements: The default implementation of this method behaves as if:
webSocket.request(1);
return null;
Returns: a CompletionStage
which completes when the message processing is done; or null
if already done
/**
* Receives a Ping message.
*
* <p> A Ping message may be sent or received by either client or
* server. It may serve either as a keepalive or as a means to verify
* that the remote endpoint is still responsive.
*
* <p> The {@code WebSocket} handles Ping messages by replying with
* appropriate Pong messages using a strategy of its choice, but within
* the boundaries of the WebSocket Protocol. The {@code WebSocket} may
* invoke {@code onPing} after handling a Ping message, before doing so
* or in parallel with it. In other words no particular ordering is
* guaranteed. If an error occurs while implementation handles this Ping
* message, then {@code onError} will be invoked with this error. For
* more details on handling Ping messages see RFC 6455 sections
* <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">5.5.2. Ping</a>
* and
* <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">5.5.3. Pong</a>.
*
* <p> The message will consist of not more than {@code 125} bytes:
* {@code message.remaining() <= 125}.
*
* <p> The {@code onPing} is invoked zero or more times in between
* {@code onOpen} and ({@code onClose} or {@code onError}).
*
* <p> If an exception is thrown from this method or the returned {@code
* CompletionStage} completes exceptionally, then {@link
* #onError(WebSocket, Throwable) onError} will be invoked with this
* exception.
*
* @implSpec The default implementation of this method behaves as if:
*
* <pre>{@code
* webSocket.request(1);
* return null;
* }</pre>
*
* @param webSocket
* the WebSocket
* @param message
* the message
*
* @return a {@code CompletionStage} which completes when the message
* processing is done; or {@code null} if already done
*/
default CompletionStage<?> onPing(WebSocket webSocket,
ByteBuffer message) {
webSocket.request(1);
return null;
}
Receives a Pong message.
A Pong message may be unsolicited or may be received in response
to a previously sent Ping. In the latter case, the contents of the
Pong is identical to the originating Ping.
The message will consist of not more than 125
bytes: message.remaining() <= 125
.
The onPong
method is invoked zero or more times in between onOpen
and (onClose
or onError
).
If an exception is thrown from this method or the returned
CompletionStage
completes exceptionally, then onError
will be invoked with this exception.
Params: - webSocket –
the WebSocket
- message –
the message
Implementation Requirements: The default implementation of this method behaves as if:
webSocket.request(1);
return null;
Returns: a CompletionStage
which completes when the message processing is done; or null
if already done
/**
* Receives a Pong message.
*
* <p> A Pong message may be unsolicited or may be received in response
* to a previously sent Ping. In the latter case, the contents of the
* Pong is identical to the originating Ping.
*
* <p> The message will consist of not more than {@code 125} bytes:
* {@code message.remaining() <= 125}.
*
* <p> The {@code onPong} method is invoked zero or more times in
* between {@code onOpen} and ({@code onClose} or {@code onError}).
*
* <p> If an exception is thrown from this method or the returned {@code
* CompletionStage} completes exceptionally, then {@link
* #onError(WebSocket, Throwable) onError} will be invoked with this
* exception.
*
* @implSpec The default implementation of this method behaves as if:
*
* <pre>{@code
* webSocket.request(1);
* return null;
* }</pre>
*
* @param webSocket
* the WebSocket
* @param message
* the message
*
* @return a {@code CompletionStage} which completes when the message
* processing is done; or {@code null} if already done
*/
default CompletionStage<?> onPong(WebSocket webSocket,
ByteBuffer message) {
webSocket.request(1);
return null;
}
Receives a Close message.
A Close message consists of a status code and a reason for closing. The status code is an integer in the range 1000 <=
code <= 65535
. The reason
is a short string that has an UTF-8 representation not longer than 123
bytes. For more details on Close message, status codes and reason see RFC 6455 sections 5.5.1. Close
and
7.4. Status Codes.
After the returned CompletionStage
has completed (normally or exceptionally), the WebSocket
completes the closing handshake by replying with an appropriate Close message.
This implementation replies with a Close message that has the
same code this message has and an empty reason.
onClose
is the last invocation on the Listener
. It is invoked at most once, but after onOpen
. If an exception is thrown from this method, it is ignored.
The WebSocket
will close at the earliest of completion of the returned CompletionStage
or sending a Close message. In particular, if a Close message has been
sent before, then this invocation completes the closing handshake and by the time this method is invoked, the WebSocket
will have been closed.
Params: - webSocket –
the WebSocket
- statusCode –
the status code
- reason –
the reason
See Also: Implementation Requirements: The default implementation of this method behaves as if:
return null;
Returns: a CompletionStage
which completes when the
WebSocket
can be closed; or null
if it can be closed immediately
/**
* Receives a Close message.
*
* <p> A Close message consists of a status code and a reason for
* closing. The status code is an integer in the range {@code 1000 <=
* code <= 65535}. The {@code reason} is a short string that has an
* UTF-8 representation not longer than {@code 123} bytes. For more
* details on Close message, status codes and reason see RFC 6455 sections
* <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">5.5.1. Close</a>
* and
* <a href="https://tools.ietf.org/html/rfc6455#section-7.4">7.4. Status Codes</a>.
*
* <p> After the returned {@code CompletionStage} has completed
* (normally or exceptionally), the {@code WebSocket} completes the
* closing handshake by replying with an appropriate Close message.
*
* <p> This implementation replies with a Close message that has the
* same code this message has and an empty reason.
*
* <p> {@code onClose} is the last invocation on the {@code Listener}.
* It is invoked at most once, but after {@code onOpen}. If an exception
* is thrown from this method, it is ignored.
*
* <p> The {@code WebSocket} will close at the earliest of completion of
* the returned {@code CompletionStage} or sending a Close message. In
* particular, if a Close message has been {@linkplain WebSocket#sendClose
* sent} before, then this invocation completes the closing handshake
* and by the time this method is invoked, the {@code WebSocket} will
* have been closed.
*
* @implSpec The default implementation of this method behaves as if:
*
* <pre>{@code
* return null;
* }</pre>
*
* @param webSocket
* the WebSocket
* @param statusCode
* the status code
* @param reason
* the reason
*
* @return a {@code CompletionStage} which completes when the {@code
* WebSocket} can be closed; or {@code null} if it can be closed immediately
*
* @see #NORMAL_CLOSURE
*/
default CompletionStage<?> onClose(WebSocket webSocket,
int statusCode,
String reason) {
return null;
}
Notifies an I/O or protocol error has occurred.
The onError
method does not correspond to any message from the WebSocket Protocol. It is a synthetic event and the last Listener
's method to be invoked. It is invoked at most once but after onOpen
. If an exception is thrown from this method, it is ignored.
Note that the WebSocket Protocol requires some errors
occur in the incoming destination must be fatal to the connection. In
such cases the implementation takes care of Failing the WebSocket
Connection: by the time onError
is invoked, the
WebSocket
will have been closed. Any outstanding or subsequent send operation will complete exceptionally with an IOException
. For more details on Failing the WebSocket Connection see RFC 6455 section 7.1.7. Fail the WebSocket Connection.
Params: - webSocket –
the WebSocket
- error –
the error
API Note: Errors associated with sending messages are reported to the CompletableFuture
s sendX
methods return, rather than to this this method. Implementation Requirements: The default implementation of this method does nothing.
/**
* Notifies an I/O or protocol error has occurred.
*
* <p> The {@code onError} method does not correspond to any message
* from the WebSocket Protocol. It is a synthetic event and the last
* {@code Listener}'s method to be invoked. It is invoked at most once
* but after {@code onOpen}. If an exception is thrown from this method,
* it is ignored.
*
* <p> Note that the WebSocket Protocol requires <i>some</i> errors
* occur in the incoming destination must be fatal to the connection. In
* such cases the implementation takes care of <i>Failing the WebSocket
* Connection</i>: by the time {@code onError} is invoked, the {@code
* WebSocket} will have been closed. Any outstanding or subsequent send
* operation will complete exceptionally with an {@code IOException}.
* For more details on Failing the WebSocket Connection see RFC 6455
* section <a href="https://tools.ietf.org/html/rfc6455#section-7.1.7">7.1.7. Fail the WebSocket Connection</a>.
*
* @apiNote Errors associated with sending messages are reported to the
* {@code CompletableFuture}s {@code sendX} methods return, rather than
* to this this method.
*
* @implSpec The default implementation of this method does nothing.
*
* @param webSocket
* the WebSocket
* @param error
* the error
*/
default void onError(WebSocket webSocket, Throwable error) { }
}
A marker used by Listener
in cases where a partial message may be received. {@Incubating} See Also: Since: 9
/**
* A marker used by {@link WebSocket.Listener} in cases where a partial
* message may be received.
* {@Incubating}
*
* @see Listener#onText(WebSocket, CharSequence, MessagePart)
* @see Listener#onBinary(WebSocket, ByteBuffer, MessagePart)
*
* @since 9
*/
enum MessagePart {
The first part of a message in a sequence.
/**
* The first part of a message in a sequence.
*/
FIRST,
A middle part of a message in a sequence.
/**
* A middle part of a message in a sequence.
*/
PART,
The last part of a message in a sequence.
/**
* The last part of a message in a sequence.
*/
LAST,
A whole message consisting of a single part.
/**
* A whole message consisting of a single part.
*/
WHOLE
}
Sends a Text message with characters from the given CharSequence
. Returns a CompletableFuture<WebSocket>
which completes normally when the message has been sent or completes exceptionally if an error occurs.
The CharSequence
must not be modified until the returned CompletableFuture
completes (either normally or exceptionally).
The returned CompletableFuture
can complete exceptionally with:
-
IllegalArgumentException
- if message
is a malformed UTF-16 sequence -
IllegalStateException
- if the WebSocket
is closed; or if a Close message has been sent; or if there is an outstanding send operation; or if a previous Binary message was sent with isLast == false
-
IOException
- if an I/O error occurs during this operation; or if the WebSocket
has been closed due to an error;
Params: - message –
the message
- isLast –
true
if this is the last part of the message, false
otherwise
Implementation Note: This implementation does not accept partial UTF-16 sequences. In case such a sequence is passed, a returned CompletableFuture
completes exceptionally with IOException
. Returns: a CompletableFuture
with this WebSocket
/**
* Sends a Text message with characters from the given {@code CharSequence}.
*
* <p> Returns a {@code CompletableFuture<WebSocket>} which completes
* normally when the message has been sent or completes exceptionally if an
* error occurs.
*
* <p> The {@code CharSequence} must not be modified until the returned
* {@code CompletableFuture} completes (either normally or exceptionally).
*
* <p> The returned {@code CompletableFuture} can complete exceptionally
* with:
* <ul>
* <li> {@link IllegalArgumentException} -
* if {@code message} is a malformed UTF-16 sequence
* <li> {@link IllegalStateException} -
* if the {@code WebSocket} is closed;
* or if a Close message has been sent;
* or if there is an outstanding send operation;
* or if a previous Binary message was sent with {@code isLast == false}
* <li> {@link IOException} -
* if an I/O error occurs during this operation;
* or if the {@code WebSocket} has been closed due to an error;
* </ul>
*
* @implNote This implementation does not accept partial UTF-16 sequences.
* In case such a sequence is passed, a returned {@code CompletableFuture}
* completes exceptionally with {@code IOException}.
*
* @param message
* the message
* @param isLast
* {@code true} if this is the last part of the message,
* {@code false} otherwise
*
* @return a {@code CompletableFuture} with this {@code WebSocket}
*/
CompletableFuture<WebSocket> sendText(CharSequence message, boolean isLast);
Sends a Binary message with bytes from the given ByteBuffer
. Returns a CompletableFuture<WebSocket>
which completes normally when the message has been sent or completes exceptionally if an error occurs.
The returned CompletableFuture
can complete exceptionally with:
-
IllegalStateException
- if the WebSocket
is closed; or if a Close message has been sent; or if there is an outstanding send operation; or if a previous Text message was sent with isLast == false
-
IOException
- if an I/O error occurs during this operation; or if the WebSocket
has been closed due to an error
Params: - message –
the message
- isLast –
true
if this is the last part of the message, false
otherwise
Returns: a CompletableFuture
with this WebSocket
/**
* Sends a Binary message with bytes from the given {@code ByteBuffer}.
*
* <p> Returns a {@code CompletableFuture<WebSocket>} which completes
* normally when the message has been sent or completes exceptionally if an
* error occurs.
*
* <p> The returned {@code CompletableFuture} can complete exceptionally
* with:
* <ul>
* <li> {@link IllegalStateException} -
* if the {@code WebSocket} is closed;
* or if a Close message has been sent;
* or if there is an outstanding send operation;
* or if a previous Text message was sent with {@code isLast == false}
* <li> {@link IOException} -
* if an I/O error occurs during this operation;
* or if the {@code WebSocket} has been closed due to an error
* </ul>
*
* @param message
* the message
* @param isLast
* {@code true} if this is the last part of the message,
* {@code false} otherwise
*
* @return a {@code CompletableFuture} with this {@code WebSocket}
*/
CompletableFuture<WebSocket> sendBinary(ByteBuffer message, boolean isLast);
Sends a Ping message with bytes from the given ByteBuffer.
Returns a CompletableFuture<WebSocket>
which completes normally when the message has been sent or completes exceptionally if an error occurs.
A Ping message may be sent or received by either client or server.
It may serve either as a keepalive or as a means to verify that the
remote endpoint is still responsive.
The message must consist of not more than 125
bytes:
message.remaining() <= 125
.
The returned CompletableFuture
can complete exceptionally with:
-
IllegalArgumentException
- if message.remaining() > 125
-
IllegalStateException
- if the WebSocket
is closed; or if a Close message has been sent; or if there is an outstanding send operation -
IOException
- if an I/O error occurs during this operation; or if the WebSocket
has been closed due to an error
Params: - message –
the message
Returns: a CompletableFuture
with this WebSocket
/**
* Sends a Ping message with bytes from the given ByteBuffer.
*
* <p> Returns a {@code CompletableFuture<WebSocket>} which completes
* normally when the message has been sent or completes exceptionally if an
* error occurs.
*
* <p> A Ping message may be sent or received by either client or server.
* It may serve either as a keepalive or as a means to verify that the
* remote endpoint is still responsive.
*
* <p> The message must consist of not more than {@code 125} bytes: {@code
* message.remaining() <= 125}.
*
* <p> The returned {@code CompletableFuture} can complete exceptionally
* with:
* <ul>
* <li> {@link IllegalArgumentException} -
* if {@code message.remaining() > 125}
* <li> {@link IllegalStateException} -
* if the {@code WebSocket} is closed;
* or if a Close message has been sent;
* or if there is an outstanding send operation
* <li> {@link IOException} -
* if an I/O error occurs during this operation;
* or if the {@code WebSocket} has been closed due to an error
* </ul>
*
* @param message
* the message
*
* @return a {@code CompletableFuture} with this {@code WebSocket}
*/
CompletableFuture<WebSocket> sendPing(ByteBuffer message);
Sends a Pong message with bytes from the given ByteBuffer.
Returns a CompletableFuture<WebSocket>
which completes normally when the message has been sent or completes exceptionally if an error occurs.
A Pong message may be unsolicited or may be sent in response to a
previously received Ping. In latter case the contents of the Pong must be
identical to the originating Ping.
The message must consist of not more than 125
bytes:
message.remaining() <= 125
.
The returned CompletableFuture
can complete exceptionally with:
-
IllegalArgumentException
- if message.remaining() > 125
-
IllegalStateException
- if the WebSocket
is closed; or if a Close message has been sent; or if there is an outstanding send operation -
IOException
- if an I/O error occurs during this operation; or if the WebSocket
has been closed due to an error
Params: - message –
the message
Returns: a CompletableFuture
with this WebSocket
/**
* Sends a Pong message with bytes from the given ByteBuffer.
*
* <p> Returns a {@code CompletableFuture<WebSocket>} which completes
* normally when the message has been sent or completes exceptionally if an
* error occurs.
*
* <p> A Pong message may be unsolicited or may be sent in response to a
* previously received Ping. In latter case the contents of the Pong must be
* identical to the originating Ping.
*
* <p> The message must consist of not more than {@code 125} bytes: {@code
* message.remaining() <= 125}.
*
* <p> The returned {@code CompletableFuture} can complete exceptionally
* with:
* <ul>
* <li> {@link IllegalArgumentException} -
* if {@code message.remaining() > 125}
* <li> {@link IllegalStateException} -
* if the {@code WebSocket} is closed;
* or if a Close message has been sent;
* or if there is an outstanding send operation
* <li> {@link IOException} -
* if an I/O error occurs during this operation;
* or if the {@code WebSocket} has been closed due to an error
* </ul>
*
* @param message
* the message
*
* @return a {@code CompletableFuture} with this {@code WebSocket}
*/
CompletableFuture<WebSocket> sendPong(ByteBuffer message);
Sends a Close message with the given status code and the reason.
When this method has been invoked, no further messages can be sent.
The statusCode
is an integer in the range 1000 <= code
<= 4999
. However, not all status codes may be legal in some implementations. Regardless of an implementation, 1000
is always legal and 1002
, 1003
, 1005
,
1006
, 1007
, 1009
, 1010
, 1012
,
1013
and 1015
are always illegal codes.
The reason
is a short string that must have an UTF-8 representation not longer than 123
bytes. For more details on Close message, status codes and reason see RFC 6455 sections 5.5.1. Close
and
7.4. Status Codes.
The method returns a CompletableFuture<WebSocket>
which completes normally when the message has been sent or completes exceptionally if an error occurs.
The returned CompletableFuture
can complete exceptionally with:
-
IllegalArgumentException
- if the statusCode
has an illegal value; or if reason
doesn't have an UTF-8 representation of length <= 123
-
IOException
- if an I/O error occurs during this operation; or the WebSocket
has been closed due to an error
If this method has already been invoked or the WebSocket
is closed, then subsequent invocations of this method have no effect and the returned CompletableFuture
completes normally.
If a Close message has been received before, then this invocation completes the closing handshake and by the time the returned CompletableFuture
completes, the WebSocket
will have been closed.
Params: - statusCode –
the status code
- reason –
the reason
Returns: a CompletableFuture
with this WebSocket
/**
* Sends a Close message with the given status code and the reason.
*
* <p> When this method has been invoked, no further messages can be sent.
*
* <p> The {@code statusCode} is an integer in the range {@code 1000 <= code
* <= 4999}. However, not all status codes may be legal in some
* implementations. Regardless of an implementation,
* <code>{@value jdk.incubator.http.WebSocket#NORMAL_CLOSURE}</code>
* is always legal and {@code 1002}, {@code 1003}, {@code 1005}, {@code
* 1006}, {@code 1007}, {@code 1009}, {@code 1010}, {@code 1012}, {@code
* 1013} and {@code 1015} are always illegal codes.
*
* <p> The {@code reason} is a short string that must have an UTF-8
* representation not longer than {@code 123} bytes. For more details on
* Close message, status codes and reason see RFC 6455 sections
* <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">5.5.1. Close</a>
* and
* <a href="https://tools.ietf.org/html/rfc6455#section-7.4">7.4. Status Codes</a>.
*
* <p> The method returns a {@code CompletableFuture<WebSocket>} which
* completes normally when the message has been sent or completes
* exceptionally if an error occurs.
*
* <p> The returned {@code CompletableFuture} can complete exceptionally
* with:
* <ul>
* <li> {@link IllegalArgumentException} -
* if the {@code statusCode} has an illegal value;
* or if {@code reason} doesn't have an UTF-8 representation of
* length {@code <= 123}
* <li> {@link IOException} -
* if an I/O error occurs during this operation;
* or the {@code WebSocket} has been closed due to an error
* </ul>
*
* <p> If this method has already been invoked or the {@code WebSocket} is
* closed, then subsequent invocations of this method have no effect and the
* returned {@code CompletableFuture} completes normally.
*
* <p> If a Close message has been {@linkplain Listener#onClose(WebSocket,
* int, String) received} before, then this invocation completes the closing
* handshake and by the time the returned {@code CompletableFuture}
* completes, the {@code WebSocket} will have been closed.
*
* @param statusCode
* the status code
* @param reason
* the reason
*
* @return a {@code CompletableFuture} with this {@code WebSocket}
*/
CompletableFuture<WebSocket> sendClose(int statusCode, String reason);
Allows n
more messages to be received by the
Listener
. The actual number of received messages might be fewer if a Close message is received, the WebSocket
closes or an error occurs.
A WebSocket
that has just been built, hasn't requested anything yet. Usually the initial request for messages is made in Listener.onOpen
.
If the WebSocket
is closed then invoking this method has no effect.
Params: - n –
the number of messages
Throws: - IllegalArgumentException – if
n < 0
Implementation Note: This implementation does not distinguish between partial and
whole messages, because it's not known beforehand how a message will be
received.
If a server sends more messages than requested, this implementation
queues up these messages on the TCP connection and may eventually force
the sender to stop sending through TCP flow control.
/**
* Allows {@code n} more messages to be received by the {@link Listener
* Listener}.
*
* <p> The actual number of received messages might be fewer if a Close
* message is received, the {@code WebSocket} closes or an error occurs.
*
* <p> A {@code WebSocket} that has just been built, hasn't requested
* anything yet. Usually the initial request for messages is made in {@link
* Listener#onOpen(jdk.incubator.http.WebSocket) Listener.onOpen}.
*
* <p> If the {@code WebSocket} is closed then invoking this method has no
* effect.
*
* @implNote This implementation does not distinguish between partial and
* whole messages, because it's not known beforehand how a message will be
* received.
*
* <p> If a server sends more messages than requested, this implementation
* queues up these messages on the TCP connection and may eventually force
* the sender to stop sending through TCP flow control.
*
* @param n
* the number of messages
*
* @throws IllegalArgumentException
* if {@code n < 0}
*/
void request(long n);
Returns a subprotocol which has been chosen for this WebSocket
. Returns: a subprotocol, or an empty String
if there is none
/**
* Returns a {@linkplain Builder#subprotocols(String, String...) subprotocol}
* which has been chosen for this {@code WebSocket}.
*
* @return a subprotocol, or an empty {@code String} if there is none
*/
String getSubprotocol();
Tells whether the WebSocket
is closed. When a WebSocket
is closed no further messages can be sent or received.
Returns: true
if the WebSocket
is closed, false
otherwise
/**
* Tells whether the {@code WebSocket} is closed.
*
* <p> When a {@code WebSocket} is closed no further messages can be sent or
* received.
*
* @return {@code true} if the {@code WebSocket} is closed,
* {@code false} otherwise
*/
boolean isClosed();
Closes the WebSocket
abruptly. This method may be invoked at any time. This method closes the underlying TCP connection and puts the WebSocket
into a closed state.
As the result
Listener.onClose
will be invoked unless either onClose
or onError
has been invoked before. In which case no additional invocation will happen.
If the WebSocket
is already closed then invoking this method has no effect.
Throws: - IOException –
if an I/O error occurs
/**
* Closes the {@code WebSocket} abruptly.
*
* <p> This method may be invoked at any time. This method closes the
* underlying TCP connection and puts the {@code WebSocket} into a closed
* state.
*
* <p> As the result {@link Listener#onClose(WebSocket, int, String)
* Listener.onClose} will be invoked unless either {@code onClose} or {@link
* Listener#onError(WebSocket, Throwable) onError} has been invoked before.
* In which case no additional invocation will happen.
*
* <p> If the {@code WebSocket} is already closed then invoking this method
* has no effect.
*
* @throws IOException
* if an I/O error occurs
*/
void abort() throws IOException;
}