src/java.net.http/share/classes/java/net/http/WebSocket.java
branchhttp-client-branch
changeset 56331 95f6f846ee8e
parent 56329 254f6c8277f9
child 56332 bf6a22cc06ba
equal deleted inserted replaced
56330:65a4ac71b2bf 56331:95f6f846ee8e
    33 import java.util.concurrent.CompletionStage;
    33 import java.util.concurrent.CompletionStage;
    34 
    34 
    35 /**
    35 /**
    36  * A WebSocket client.
    36  * A WebSocket client.
    37  *
    37  *
    38  * <p> To create a {@code WebSocket} use the {@link HttpClient#newWebSocketBuilder}
    38  * <p> To create a WebSocket use the {@link HttpClient#newWebSocketBuilder}
    39  * method. To close a {@code WebSocket} use one of the {@code sendClose} or
    39  * method. To close a WebSocket use one of the {@code sendClose} or
    40  * {@code abort} methods.
    40  * {@code abort} methods.
    41  *
    41  *
    42  * <p> WebSocket messages are sent through a {@code WebSocket} and received
    42  * <p> WebSocket messages are sent through a {@code WebSocket} and received
    43  * through the {@code WebSocket.Listener}. Messages can be sent until
    43  * through the {@code WebSocket.Listener}. Messages can be sent until
    44  * the output is closed, and received until the input is closed.
    44  * the output is closed, and received until the input is closed.
    50  * completes normally if the message is sent or completes exceptionally if an
    50  * completes normally if the message is sent or completes exceptionally if an
    51  * error occurs.
    51  * error occurs.
    52  *
    52  *
    53  * A <i>receive method</i> is any of the {@code onText}, {@code onBinary},
    53  * A <i>receive method</i> is any of the {@code onText}, {@code onBinary},
    54  * {@code onPing}, {@code onPong} and {@code onClose} methods of
    54  * {@code onPing}, {@code onPong} and {@code onClose} methods of
    55  * {@code Listener}. A {@code WebSocket} maintains an internal counter.
    55  * {@code Listener}. A WebSocket maintains an internal counter.
    56  * This counter indicates how many invocations of the associated listener's
    56  * This counter indicates how many invocations of the associated listener's
    57  * receive methods have been requested, but not yet made. While this counter is
    57  * receive methods have been requested, but not yet made. While this counter is
    58  * zero the {@code WebSocket} does not invoke any of the receive methods. The
    58  * zero the WebSocket does not invoke any of the receive methods. The
    59  * counter is incremented by {@code n} when {@code request(n)} is called. The
    59  * counter is incremented by {@code n} when {@code request(n)} is called. The
    60  * counter is decremented by one when the {@code WebSocket} invokes a receive
    60  * counter is decremented by one when the WebSocket invokes a receive method.
    61  * method. {@code onError} is not a receive method. The {@code WebSocket} may
    61  * {@code onOpen} and {@code onError} are not receive methods. WebSocket invokes
    62  * invoke {@code onError} at any given time. If the {@code WebSocket} invokes
    62  * {@code onOpen} prior to any other methods on the listener. WebSocket may
       
    63  * invoke {@code onError} at any given time. If the WebSocket invokes
    63  * {@code onError} or {@code onClose}, then no further listener methods will be
    64  * {@code onError} or {@code onClose}, then no further listener methods will be
    64  * invoked, no matter the value of the counter. For a newly built
    65  * invoked, no matter the value of the counter. For a newly built WebSocket the
    65  * {@code WebSocket} the value of the counter is zero.
    66  * value of the counter is zero.
    66  *
    67  *
    67  * <p> When sending or receiving a message in parts, a whole message is
    68  * <p> When sending or receiving a message in parts, a whole message is
    68  * transferred as a sequence of one or more invocations where the last
    69  * transferred as a sequence of one or more invocations where the last
    69  * invocation is identified via an additional method argument.
    70  * invocation is identified via an additional method argument.
    70  *
    71  *
    71  * <p> Unless otherwise stated, {@code null} arguments will cause methods
    72  * <p> Unless otherwise stated, {@code null} arguments will cause methods
    72  * of {@code WebSocket} to throw {@code NullPointerException}, similarly,
    73  * of {@code WebSocket} to throw {@code NullPointerException}, similarly,
    73  * {@code WebSocket} will not pass {@code null} arguments to methods of
    74  * {@code WebSocket} will not pass {@code null} arguments to methods of
    74  * {@code Listener}.
    75  * {@code Listener}.
    75  *
    76  *
    76  * <p> The state of a {@code WebSocket} is not changed by the invocations that
    77  * <p> The state of a WebSocket is not changed by the invocations that throw or
    77  * throw or return a {@code CompletableFuture} that completes with one of the
    78  * return a {@code CompletableFuture} that completes with one of the
    78  * {@code NullPointerException}, {@code IllegalArgumentException},
    79  * {@code NullPointerException}, {@code IllegalArgumentException},
    79  * {@code IllegalStateException} exceptions.
    80  * {@code IllegalStateException} exceptions.
    80  *
    81  *
    81  * <p> A {@code WebSocket} invokes methods of its listener in a thread-safe
    82  * <p> A WebSocket invokes methods on the associated listener in a thread-safe
    82  * manner.
    83  * manner.
    83  *
    84  *
    84  * <p> {@code WebSocket} handles Ping and Close messages automatically (as per
    85  * <p> {@code WebSocket} handles Ping and Close messages automatically (as per
    85  * RFC 6455) by replying with Pong and Close messages respectively. If the
    86  * RFC 6455) by replying with Pong and Close messages respectively. If the
    86  * listener receives Ping or Close messages, no mandatory actions from the
    87  * listener receives Ping or Close messages, no mandatory actions from the
   401             webSocket.request(1);
   402             webSocket.request(1);
   402             return null;
   403             return null;
   403         }
   404         }
   404 
   405 
   405         /**
   406         /**
   406          * Receives a Close message indicating the {@code WebSocket}'s input has
   407          * Receives a Close message indicating the WebSocket's input has been
   407          * been closed.
   408          * closed.
   408          *
   409          *
   409          * <p> This is the last invocation from the {@code WebSocket}. By the
   410          * <p> This is the last invocation from the {@code WebSocket}. By the
   410          * time this invocation begins the {@code WebSocket}'s input will have
   411          * time this invocation begins the WebSocket's input will have
   411          * been closed. Be prepared to receive this invocation at any time after
   412          * been closed. Be prepared to receive this invocation at any time after
   412          * {@code onOpen} regardless of whether or not any messages have been
   413          * {@code onOpen} regardless of whether or not any messages have been
   413          * requested from the {@code WebSocket}.
   414          * requested from the {@code WebSocket}.
   414          *
   415          *
   415          * <p> A Close message consists of a status code and a reason for
   416          * <p> A Close message consists of a status code and a reason for
   416          * closing. The status code is an integer from the range
   417          * closing. The status code is an integer from the range
   417          * {@code 1000 <= code <= 65535}. The {@code reason} is a string which
   418          * {@code 1000 <= code <= 65535}. The {@code reason} is a string which
   418          * has an UTF-8 representation not longer than {@code 123} bytes.
   419          * has an UTF-8 representation not longer than {@code 123} bytes.
   419          *
   420          *
   420          * <p> If the {@code WebSocket}'s output is not already closed, the
   421          * <p> If the WebSocket's output is not already closed, the
   421          * {@code CompletionStage} returned by this method will be used as an
   422          * {@code CompletionStage} returned by this method will be used as an
   422          * indication that the {@code WebSocket}'s output may be closed. The
   423          * indication that the WebSocket's output may be closed. The WebSocket
   423          * {@code WebSocket} will close its output at the earliest of completion
   424          * will close its output at the earliest of completion of the returned
   424          * of the returned {@code CompletionStage} or invoking either of the
   425          * {@code CompletionStage} or invoking either of the {@code sendClose}
   425          * {@code sendClose} or {@code abort} methods.
   426          * or {@code abort} methods.
   426          *
   427          *
   427          * @apiNote Returning a {@code CompletionStage} that never completes,
   428          * @apiNote Returning a {@code CompletionStage} that never completes,
   428          * effectively disables the reciprocating closure of the output.
   429          * effectively disables the reciprocating closure of the output.
   429          *
   430          *
   430          * <p> To specify a custom closure code and/or reason code the sendClose
   431          * <p> To specify a custom closure code and/or reason code the sendClose
   431          * may be invoked from inside onClose call:
   432          * may be invoked from inside onClose call:
   432          * <pre>{@code
   433          * <pre>{@code
   433          *  public CompletionStage<?> onClose(WebSocket webSocket,
   434          *  public CompletionStage<?> onClose(WebSocket webSocket,
   434          *                             int statusCode,
   435          *                                    int statusCode,
   435          *                             String reason) {
   436          *                                    String reason) {
   436          *      webSocket.sendClose(CUSTOM_STATUS_CODE, CUSTOM_REASON);
   437          *      webSocket.sendClose(CUSTOM_STATUS_CODE, CUSTOM_REASON);
   437          *      return new CompletableFuture<Void>();
   438          *      return new CompletableFuture<Void>();
   438          *  }
   439          *  }
   439          * }</pre>
   440          * }</pre>
   440          *
   441          *
   460         }
   461         }
   461 
   462 
   462         /**
   463         /**
   463          * An error has occurred.
   464          * An error has occurred.
   464          *
   465          *
   465          * <p> This is the last invocation from the {@code WebSocket}. By the
   466          * <p> This is the last invocation from the specified WebSocket. By the
   466          * time this invocation begins both {@code WebSocket}'s input and output
   467          * time this invocation begins both that WebSocket's input and output
   467          * will have been closed. Be prepared to receive this invocation at any
   468          * will have been closed. A WebSocket may invoke this method on the
   468          * time after {@code onOpen} regardless of whether or not any messages
   469          * associated listener at any time after it has invoked {@code onOpen},
   469          * have been requested from the {@code WebSocket}.
   470          * regardless of whether or not any invocations have been requested from
       
   471          * the WebSocket.
   470          *
   472          *
   471          * <p> If an exception is thrown from this method, resulting behavior is
   473          * <p> If an exception is thrown from this method, resulting behavior is
   472          * undefined.
   474          * undefined.
   473          *
   475          *
   474          * @param webSocket
   476          * @param webSocket
   504      *         the message
   506      *         the message
   505      * @param last
   507      * @param last
   506      *         {@code true} if this is the last part of the message,
   508      *         {@code true} if this is the last part of the message,
   507      *         {@code false} otherwise
   509      *         {@code false} otherwise
   508      *
   510      *
   509      * @return a {@code CompletableFuture} that completes, with this
   511      * @return a {@code CompletableFuture} that completes, with this WebSocket,
   510      * {@code WebSocket}, when the message has been sent
   512      * when the message has been sent
   511      */
   513      */
   512     CompletableFuture<WebSocket> sendText(CharSequence message, boolean last);
   514     CompletableFuture<WebSocket> sendText(CharSequence message, boolean last);
   513 
   515 
   514     /**
   516     /**
   515      * Sends a Binary message with bytes from the given {@code ByteBuffer}.
   517      * Sends a Binary message with bytes from the given {@code ByteBuffer}.
   534      *         the message
   536      *         the message
   535      * @param last
   537      * @param last
   536      *         {@code true} if this is the last part of the message,
   538      *         {@code true} if this is the last part of the message,
   537      *         {@code false} otherwise
   539      *         {@code false} otherwise
   538      *
   540      *
   539      * @return a {@code CompletableFuture} that completes, with this
   541      * @return a {@code CompletableFuture} that completes, with this WebSocket,
   540      * {@code WebSocket}, when the message has been sent
   542      * when the message has been sent
   541      */
   543      */
   542     CompletableFuture<WebSocket> sendBinary(ByteBuffer message, boolean last);
   544     CompletableFuture<WebSocket> sendBinary(ByteBuffer message, boolean last);
   543 
   545 
   544     /**
   546     /**
   545      * Sends a Ping message with bytes from the given {@code ByteBuffer}.
   547      * Sends a Ping message with bytes from the given {@code ByteBuffer}.
   561      * </ul>
   563      * </ul>
   562      *
   564      *
   563      * @param message
   565      * @param message
   564      *         the message
   566      *         the message
   565      *
   567      *
   566      * @return a {@code CompletableFuture} that completes, with this
   568      * @return a {@code CompletableFuture} that completes, with this WebSocket,
   567      * {@code WebSocket}, when the Ping message has been sent
   569      * when the Ping message has been sent
   568      */
   570      */
   569     CompletableFuture<WebSocket> sendPing(ByteBuffer message);
   571     CompletableFuture<WebSocket> sendPing(ByteBuffer message);
   570 
   572 
   571     /**
   573     /**
   572      * Sends a Pong message with bytes from the given {@code ByteBuffer}.
   574      * Sends a Pong message with bytes from the given {@code ByteBuffer}.
   588      * </ul>
   590      * </ul>
   589      *
   591      *
   590      * @param message
   592      * @param message
   591      *         the message
   593      *         the message
   592      *
   594      *
   593      * @return a {@code CompletableFuture} that completes, with this
   595      * @return a {@code CompletableFuture} that completes, with this WebSocket,
   594      * {@code WebSocket}, when the Pong message has been sent
   596      * when the Pong message has been sent
   595      */
   597      */
   596     CompletableFuture<WebSocket> sendPong(ByteBuffer message);
   598     CompletableFuture<WebSocket> sendPong(ByteBuffer message);
   597 
   599 
   598     /**
   600     /**
   599      * Initiates an orderly closure of this {@code WebSocket}'s output by
   601      * Initiates an orderly closure of this WebSocket's output by
   600      * sending a Close message with the given status code and the reason.
   602      * sending a Close message with the given status code and the reason.
   601      *
   603      *
   602      * <p> The {@code statusCode} is an integer from the range
   604      * <p> The {@code statusCode} is an integer from the range
   603      * {@code 1000 <= code <= 4999}. Status codes {@code 1002}, {@code 1003},
   605      * {@code 1000 <= code <= 4999}. Status codes {@code 1002}, {@code 1003},
   604      * {@code 1006}, {@code 1007}, {@code 1009}, {@code 1010}, {@code 1012},
   606      * {@code 1006}, {@code 1007}, {@code 1009}, {@code 1010}, {@code 1012},
   618      * <p> Unless the {@code CompletableFuture} returned from this method
   620      * <p> Unless the {@code CompletableFuture} returned from this method
   619      * completes with {@code IllegalArgumentException}, or the method throws
   621      * completes with {@code IllegalArgumentException}, or the method throws
   620      * {@code NullPointerException}, the output will be closed.
   622      * {@code NullPointerException}, the output will be closed.
   621      *
   623      *
   622      * <p> If not already closed, the input remains open until it is
   624      * <p> If not already closed, the input remains open until it is
   623      * {@linkplain Listener#onClose(WebSocket, int, String) closed} by the server,
   625      * {@linkplain Listener#onClose(WebSocket, int, String) closed} by the
   624      * or {@code abort} is invoked, or an
   626      * server, or {@code abort} is invoked, or an
   625      * {@linkplain Listener#onError(WebSocket, Throwable) error} occurs.
   627      * {@linkplain Listener#onError(WebSocket, Throwable) error} occurs.
   626      *
   628      *
   627      * @apiNote Use the provided integer constant {@link #NORMAL_CLOSURE} as a
   629      * @apiNote Use the provided integer constant {@link #NORMAL_CLOSURE} as a
   628      * status code and an empty string as a reason in a typical case
   630      * status code and an empty string as a reason in a typical case
   629      * <pre>{@code
   631      * <pre>{@code
   637      * @param statusCode
   639      * @param statusCode
   638      *         the status code
   640      *         the status code
   639      * @param reason
   641      * @param reason
   640      *         the reason
   642      *         the reason
   641      *
   643      *
   642      * @return a {@code CompletableFuture} that completes, with this
   644      * @return a {@code CompletableFuture} that completes, with this WebSocket,
   643      * {@code WebSocket}, when the Close message has been sent
   645      * when the Close message has been sent
   644      */
   646      */
   645     CompletableFuture<WebSocket> sendClose(int statusCode, String reason);
   647     CompletableFuture<WebSocket> sendClose(int statusCode, String reason);
   646 
   648 
   647     /**
   649     /**
   648      * Increments the counter of invocations requested from this
   650      * Increments the counter of invocations requested from this WebSocket.
   649      * {@code WebSocket} to the associated listener by the given number.
       
   650      *
   651      *
   651      * <p> This WebSocket will invoke {@code onText}, {@code onBinary},
   652      * <p> This WebSocket will invoke {@code onText}, {@code onBinary},
   652      * {@code onPing}, {@code onPong} or {@code onClose} methods on the
   653      * {@code onPing}, {@code onPong} or {@code onClose} methods on the
   653      * associated listener up to {@code n} more times.
   654      * associated listener up to {@code n} more times.
   654      *
   655      *
   655      * @apiNote The parameter of this method is the number of invocations being
   656      * @apiNote The parameter of this method is the number of invocations being
   656      * requested from this {@code WebSocket} to the associated {@code Listener},
   657      * requested from this WebSocket to the associated listener, not the number
   657      * not the number of messages. Sometimes a message may be delivered in a
   658      * of messages. Sometimes a message may be delivered to the listener in a
   658      * single invocation, but not always. For example, Ping, Pong and Close
   659      * single invocation, but not always. For example, Ping, Pong and Close
   659      * messages are delivered in a single invocation of {@code onPing},
   660      * messages are delivered in a single invocation of {@code onPing},
   660      * {@code onPong} and {@code onClose} respectively. However, whether or not
   661      * {@code onPong} and {@code onClose} respectively. However, whether or not
   661      * Text and Binary messages are delivered in a single invocation of
   662      * Text and Binary messages are delivered in a single invocation of
   662      * {@code onText} and {@code onBinary} depends on the boolean argument
   663      * {@code onText} and {@code onBinary} depends on the boolean argument
   692      *         if {@code n <= 0}
   693      *         if {@code n <= 0}
   693      */
   694      */
   694     void request(long n);
   695     void request(long n);
   695 
   696 
   696     /**
   697     /**
   697      * Returns the subprotocol for this {@code WebSocket}.
   698      * Returns the subprotocol used by this WebSocket.
   698      *
   699      *
   699      * @return the subprotocol for this {@code WebSocket}, or an empty
   700      * @return the subprotocol, or an empty string if there's no subprotocol
   700      * {@code String} if there's no subprotocol
       
   701      */
   701      */
   702     String getSubprotocol();
   702     String getSubprotocol();
   703 
   703 
   704     /**
   704     /**
   705      * Tells whether this {@code WebSocket}'s output is closed.
   705      * Tells whether this WebSocket's output is closed.
   706      *
   706      *
   707      * <p> If this method returns {@code true}, subsequent invocations will also
   707      * <p> If this method returns {@code true}, subsequent invocations will also
   708      * return {@code true}.
   708      * return {@code true}.
   709      *
   709      *
   710      * @return {@code true} if closed, {@code false} otherwise
   710      * @return {@code true} if closed, {@code false} otherwise
   711      */
   711      */
   712     boolean isOutputClosed();
   712     boolean isOutputClosed();
   713 
   713 
   714     /**
   714     /**
   715      * Tells whether this {@code WebSocket}'s input is closed.
   715      * Tells whether this WebSocket's input is closed.
   716      *
   716      *
   717      * <p> If this method returns {@code true}, subsequent invocations will also
   717      * <p> If this method returns {@code true}, subsequent invocations will also
   718      * return {@code true}.
   718      * return {@code true}.
   719      *
   719      *
   720      * @return {@code true} if closed, {@code false} otherwise
   720      * @return {@code true} if closed, {@code false} otherwise
   721      */
   721      */
   722     boolean isInputClosed();
   722     boolean isInputClosed();
   723 
   723 
   724     /**
   724     /**
   725      * Closes this {@code WebSocket}'s input and output abruptly.
   725      * Closes this WebSocket's input and output abruptly.
   726      *
   726      *
   727      * <p> When this method returns both the input and the output will have been
   727      * <p> When this method returns both the input and the output will have been
   728      * closed. Any pending send operations will fail with {@code IOException}.
   728      * closed. Any pending send operations will fail with {@code IOException}.
   729      * Subsequent invocations of {@code abort()} will have no effect.
   729      * Subsequent invocations of {@code abort} will have no effect.
   730      */
   730      */
   731     void abort();
   731     void abort();
   732 }
   732 }