# HG changeset patch # User prappo # Date 1521632370 0 # Node ID 161f716753d7545e54f59262211570fb8c149e94 # Parent efd50952acd99447b46ec75ae891be226ec2cbe8 http-client-branch: (WebSocket) API wording for back-pressure diff -r efd50952acd9 -r 161f716753d7 src/java.net.http/share/classes/java/net/http/WebSocket.java --- a/src/java.net.http/share/classes/java/net/http/WebSocket.java Wed Mar 21 10:25:26 2018 +0000 +++ b/src/java.net.http/share/classes/java/net/http/WebSocket.java Wed Mar 21 11:39:30 2018 +0000 @@ -40,7 +40,7 @@ * {@code abort} methods. * *
WebSocket messages are sent through a {@code WebSocket} and received - * through the {@code WebSocket}'s {@code Listener}. Messages can be sent until + * through the {@code WebSocket.Listener}. Messages can be sent until * the output is closed, and received until the input is closed. * A {@code WebSocket} whose output and input are both closed may be considered * itself closed. To check these states use {@link #isOutputClosed()} and @@ -50,12 +50,19 @@ * completes normally if the message is sent or completes exceptionally if an * error occurs. * - *
To receive a message, first request it. If {@code n} messages are - * requested, the listener will receive up to {@code n} more invocations of the - * designated methods from the {@code WebSocket}. To request messages use - * {@link #request(long)}. Request is an additive operation, that is - * {@code request(n)} followed by {@code request(m)} is equivalent to - * {@code request(n + m)}. + * A receive method is any of the {@code onText}, {@code onBinary}, + * {@code onPing}, {@code onPong} and {@code onClose} methods of + * {@code Listener}. A {@code WebSocket} maintains an internal counter. + * This counter indicates how many invocations of the associated listener's + * receive methods have been requested, but not yet made. While this counter is + * zero the {@code WebSocket} does not invoke any of the receive methods. The + * counter is incremented by {@code n} when {@code request(n)} is called. The + * counter is decremented by one when the {@code WebSocket} invokes a receive + * method. {@code onError} is not a receive method. The {@code WebSocket} may + * invoke {@code onError} at any given time. If the {@code WebSocket} invokes + * {@code onError} or {@code onClose}, then no further listener methods will be + * invoked, no matter the value of the counter. For a newly built + * {@code WebSocket} the value of the counter is zero. * *
When sending or receiving a message in parts, a whole message is
* transferred as a sequence of one or more invocations where the last
@@ -79,6 +86,10 @@
* listener receives Ping or Close messages, no mandatory actions from the
* listener are required.
*
+ * @apiNote The relationship between a WebSocket and an instance of Listener
+ * associated with it is analogous to that of Subscription and the related
+ * Subscriber of type {@link java.util.concurrent.Flow}.
+ *
* @since 11
*/
public interface WebSocket {
@@ -635,14 +646,48 @@
CompletableFuture This WebSocket will invoke {@code onText}, {@code onBinary},
+ * {@code onPing}, {@code onPong} or {@code onClose} methods on the
+ * associated listener up to {@code n} more times.
+ *
+ * @apiNote The parameter of this method is the number of invocations being
+ * requested from this {@code WebSocket} to the associated {@code Listener},
+ * not the number of messages. Sometimes a message may be delivered in a
+ * single invocation, but not always. For example, Ping, Pong and Close
+ * messages are delivered in a single invocation of {@code onPing},
+ * {@code onPong} and {@code onClose} respectively. However, whether or not
+ * Text and Binary messages are delivered in a single invocation of
+ * {@code onText} and {@code onBinary} depends on the boolean argument
+ * ({@code last}) of these methods. If {@code last} is {@code false}, then
+ * there is more to a message than has been delivered to the invocation.
*
- * This {@code WebSocket} will invoke its listener's {@code onText},
- * {@code onBinary}, {@code onPing}, {@code onPong} or {@code onClose}
- * methods up to {@code n} more times.
+ * Here is an example of a listener that requests invocations, one at a
+ * time, until a complete message has been accumulated, then processes the
+ * result:
+ * WebSocket.Listener listener = new WebSocket.Listener() {
+ *
+ * StringBuilder text = new StringBuilder();
+ *
+ * @Override
+ * public CompletionStage<?> onText(WebSocket webSocket,
+ * CharSequence message,
+ * boolean last) {
+ * text.append(message);
+ * if (last) {
+ * processCompleteTextMessage(text);
+ * text = new StringBuilder();
+ * }
+ * webSocket.request(1);
+ * return null;
+ * }
+ * ...
+ * }
*
* @param n
- * the number of messages requested
+ * the number of invocations
*
* @throws IllegalArgumentException
* if {@code n <= 0}
diff -r efd50952acd9 -r 161f716753d7 test/jdk/java/net/httpclient/examples/WebSocketExample.java
--- a/test/jdk/java/net/httpclient/examples/WebSocketExample.java Wed Mar 21 10:25:26 2018 +0000
+++ b/test/jdk/java/net/httpclient/examples/WebSocketExample.java Wed Mar 21 11:39:30 2018 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, 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
@@ -28,6 +28,7 @@
import java.net.http.HttpClient;
import java.net.http.WebSocket;
+import java.util.concurrent.CompletionStage;
/*
* THE CONTENTS OF THIS FILE HAVE TO BE IN SYNC WITH THE EXAMPLES USED IN THE
@@ -56,4 +57,26 @@
CompletableFuture