Hi,

Could you please [*] review the following change for the upcoming JDK-8159053?
This change addresses:

1. Listener.onClose/onPing behaviour, making the implementation fully*
responsible of protocol compliance. So reactions on onClose/onPing cannot be
overridden/redefined in a Listener

2. Simpler representation of the Close message.

    /**
     * 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 behaves as if:
     *
     * <pre>{@code
     *     webSocket.request(1);
     *     return CompletableFuture.completedStage(null);
     * }</pre>
     *
     * @param webSocket
     *         the WebSocket
     * @param message
     *         the message
     *
     * @return a CompletionStage that 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.
     *
     * <p> Once a Close message is received, the server will not send any
     * more messages.
     *
     * <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 reason is a short string that has an UTF-8
     * representation not longer than {@code 123} bytes.
     *
     * <p> For more information on status codes and reasons see
     * <a href="https://tools.ietf.org/html/rfc6455#section-7.4";>RFC 6455, 7.4. 
Status Codes</a>.
     *
     * <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> After a Close message has been received, the implementation will
     * close the connection automatically. However, the client is allowed to
     * finish sending the current sequence of partial message first. To
     * facilitate it, the WebSocket implementation expects this method to
     * return a {@code CompletionStage}. The implementation then will
     * attempt to close the connection at the earliest of, either the
     * completion of the returned {@code CompletionStage} or the last part
     * of the current message has been sent.
     *
     * @implSpec The default implementation behaves as if:
     *
     * <pre>{@code
     *     return CompletableFuture.completedStage(null);
     * }</pre>
     *
     * @param webSocket
     *         the WebSocket
     * @param statusCode
     *         the status code
     * @param reason
     *         the reason
     *
     * @return a CompletionStage that when completed will trigger closing of
     * the WebSocket
     */
    default CompletionStage<?> onClose(WebSocket webSocket,
                                       int statusCode,
                                       String reason) {
        return null;
    }

    /**
     * Sends a Close message with the given status code and the reason.
     *
     * <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 statusCode} is an integer in the range {@code 1000 <= code
     * <= 4999}, except for {@code 1004}, {@code 1005}, {@code 1006} and {@code
     * 1015}. The {@code reason} is a short string that must have an UTF-8
     * representation not longer than {@code 123} bytes.
     *
     * <p> For more information about status codes see
     * <a href="https://tools.ietf.org/html/rfc6455#section-7.4";>RFC 6455, 7.4. 
Status Codes</a>.)
     *
     * <p> If a Close message has been already sent or the {@code WebSocket} is
     * closed, then invoking this method has no effect and returned {@code
     * CompletableFuture} completes normally.
     *
     * <p> The returned {@code CompletableFuture} can complete exceptionally
     * with:
     * <ul>
     * <li> {@link IOException}
     *          if an I/O error occurs during this operation
     * </ul>
     *
     * @param statusCode
     *         the status code
     * @param reason
     *         the reason
     *
     * @return a CompletableFuture with this WebSocket
     *
     * @throws IllegalArgumentException
     *         if the {@code statusCode} has an illegal value, or
     *         {@code reason} doesn't have an UTF-8 representation not longer
     *         than {@code 123} bytes
     *
     * @see #sendClose()
     */
    CompletableFuture<WebSocket> sendClose(int statusCode, String reason);

    /**
     * Sends an empty Close message.
     *
     * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
     * normally when the message has been sent or completes exceptionally if an
     * error occurs.
     *
     * <p> If a Close message has been already sent or the {@code WebSocket} is
     * closed, then invoking this method has no effect and returned {@code
     * CompletableFuture} completes normally.
     *
     * <p> The returned {@code CompletableFuture} can complete exceptionally
     * with:
     * <ul>
     * <li> {@link IOException}
     *          if an I/O error occurs during this operation
     * </ul>
     *
     * @return a CompletableFuture with this WebSocket
     */
    CompletableFuture<WebSocket> sendClose();

Thanks,
-Pavel

--------------------------------------------------------------------------------
[1] Please excuse me for not publishing this in a form of a webrev. The reason
is that currently there are too many outstanding changes in the queue that would
simply obscure the review.

Reply via email to