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.