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}. |
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 } |