WebSocket实例是通过WebSocket.Builder创建的。
WebSocket有一个输入端和一个输出端。这两个端是相互独立的。一个端可以是打开或关闭状态。一旦关闭,端将保持关闭状态。WebSocket消息通过WebSocket发送并通过与之关联的WebSocket.Listener接收。消息可以发送直到WebSocket的输出关闭,并且可以接收直到WebSocket的输入关闭。
发送方法是WebSocket的sendText、sendBinary、sendPing、sendPong和sendClose方法中的任何一个。发送方法启动发送操作并返回一个CompletableFuture,一旦操作完成,该CompletableFuture就会完成。如果CompletableFuture正常完成,则操作被视为成功。如果CompletableFuture异常完成,则操作被视为失败。已经启动但尚未完成的操作被视为挂起。
接收方法是Listener的onText、onBinary、onPing、onPong和onClose方法中的任何一个。WebSocket通过在侦听器上调用接收方法来启动接收操作。然后,侦听器必须返回一个CompletionStage,一旦操作完成,该CompletionStage就会完成。
为了控制消息的接收,WebSocket维护一个内部计数器。该计数器的值是WebSocket尚未调用接收方法的次数。当此计数器为零时,WebSocket不会调用接收方法。当调用request(n)时,计数器会增加n。当WebSocket调用接收方法时,计数器会减少一。 onOpen和onError不是接收方法。WebSocket在侦听器上的任何其他方法之前调用onOpen。WebSocket最多调用一次onOpen。WebSocket可能在任何时间调用onError。如果WebSocket调用onError或onClose,则不会再调用任何其他侦听器方法,无论计数器的值如何。对于新构建的WebSocket,计数器为零。
除非另有说明,否则null参数将导致WebSocket的方法抛出NullPointerException,同样,WebSocket不会将null参数传递给Listener的方法。通过引发或返回以NullPointerException、IllegalArgumentException、IllegalStateException异常之一完成的CompletableFuture的调用不会更改WebSocket的状态。
WebSocket根据WebSocket协议自动处理接收到的Ping和Close消息,通过回复Pong和Close消息。如果侦听器接收到Ping或Close消息,则不需要侦听器执行任何强制操作。
- API注释:
-
WebSocket与关联的Listener之间的关系类似于Subscription和类型为
Flow的关联Subscriber之间的关系。 - 自 JDK 版本:
- 11
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic interfaceWebSocket客户端的构建器。static interfaceWebSocket的接收接口。 -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intWebSocket Close消息的状态码(1000),表示正常关闭,意味着建立连接的目的已实现。 -
Method Summary
Modifier and TypeMethodDescriptionvoidabort()突然关闭此WebSocket的输入和输出。返回此WebSocket使用的子协议。boolean告知此WebSocket的输入是否已关闭。boolean告知此WebSocket的输出是否已关闭。voidrequest(long n) 增加接收方法调用次数的计数器。sendBinary(ByteBuffer data, boolean last) 使用给定缓冲区中的字节发送二进制数据。通过发送具有给定状态码和原因的Close消息,启动此WebSocket输出的有序关闭。sendPing(ByteBuffer message) 使用给定缓冲区中的字节发送Ping消息。sendPong(ByteBuffer message) 使用给定缓冲区中的字节发送Pong消息。sendText(CharSequence data, boolean last) 使用给定字符序列中的字符发送文本数据。
-
Field Details
-
NORMAL_CLOSURE
static final int NORMAL_CLOSUREWebSocket Close消息的状态码(1000),表示正常关闭,意味着建立连接的目的已实现。- 参见:
-
-
Method Details
-
sendText
使用给定字符序列中的字符发送文本数据。在此方法返回的
CompletableFuture完成之前,不得修改字符序列。此方法返回的
CompletableFuture可能会以异常方式完成:IllegalStateException- 如果存在待处理的文本或二进制发送操作,或者如果先前的二进制数据未完成消息IOException- 如果发生I/O错误,或者如果输出已关闭
- 实现注释:
-
如果
data是格式不正确的UTF-16序列,则操作将失败并引发IOException。 - 参数:
-
data- 数据 -
last- 如果此调用完成消息,则为true,否则为false - 返回:
-
一个
CompletableFuture,当数据已发送时,将完成此WebSocket
-
sendBinary
使用给定缓冲区中的字节发送二进制数据。数据位于缓冲区的位置到限制之间的字节中。通过此方法返回的
CompletableFuture正常完成后,缓冲区将不再有剩余字节。在此之后不得访问缓冲区。此方法返回的
CompletableFuture可能会以异常方式完成:IllegalStateException- 如果存在待处理的文本或二进制发送操作,或者如果先前的文本数据未完成消息IOException- 如果发生I/O错误,或者如果输出已关闭
- 参数:
-
data- 数据 -
last- 如果此调用完成消息,则为true,否则为false - 返回:
-
一个
CompletableFuture,当数据已发送时,将完成此WebSocket
-
sendPing
使用给定缓冲区中的字节发送Ping消息。消息由缓冲区的位置到限制之间的不超过
125字节组成。通过此方法返回的CompletableFuture正常完成后,缓冲区将不再有剩余字节。在此之后不得访问缓冲区。此方法返回的
CompletableFuture可能会以异常方式完成:IllegalStateException- 如果存在待处理的ping或pong发送操作IllegalArgumentException- 如果消息过长IOException- 如果发生I/O错误,或者如果输出已关闭
- 参数:
-
message- 消息 - 返回:
-
一个
CompletableFuture,当Ping消息已发送时,将完成此WebSocket
-
sendPong
使用给定缓冲区中的字节发送Pong消息。消息由缓冲区的位置到限制之间的不超过
125字节组成。通过此方法返回的CompletableFuture正常完成后,缓冲区将不再有剩余字节。在此之后不得访问缓冲区。鉴于WebSocket实现将在接收到ping时自动发送一个对应的pong,因此很少需要显式发送pong消息。
此方法返回的
CompletableFuture可能会以异常方式完成:IllegalStateException- 如果存在待处理的ping或pong发送操作IllegalArgumentException- 如果消息过长IOException- 如果发生I/O错误,或者如果输出已关闭
- 参数:
-
message- 消息 - 返回:
-
一个
CompletableFuture,当Pong消息已发送时,将完成此WebSocket
-
sendClose
发送带有给定状态码和原因的Close消息,通过发送Close消息来有序关闭此WebSocket的输出。statusCode是一个整数,范围为1000 <= code <= 4999。状态码1002、1003、1006、1007、1009、1010、1012、1013和1015是非法的。关于其他状态码的行为是特定于实现的。合法的reason是一个UTF-8表示不超过123字节的字符串。从此方法返回的
CompletableFuture可能会异常完成:IllegalArgumentException- 如果statusCode是非法的,或者reason是非法的IOException- 如果发生I/O错误,或者输出已关闭
除非从此方法返回的
CompletableFuture以IllegalArgumentException完成,或者该方法抛出NullPointerException,否则输出将被关闭。如果尚未关闭,则输入保持打开,直到接收到Close消息,或调用
abort,或发生错误。- API注释:
-
在典型情况下,使用提供的整数常量
NORMAL_CLOSURE作为状态码,以及空字符串作为原因:CompletableFuture<WebSocket> webSocket = ... webSocket.thenCompose(ws -> ws.sendText("Hello, ", false)) .thenCompose(ws -> ws.sendText("world!", true)) .thenCompose(ws -> ws.sendClose(WebSocket.NORMAL_CLOSURE, "")) .join();sendClose方法不会关闭此WebSocket的输入。它仅通过发送Close消息关闭此WebSocket的输出。要强制关闭输入,请调用abort方法。以下是一个发送Close消息然后启动计时器的应用程序示例。一旦在指定的超时时间内未收到任何数据,计时器将触发并中止WebSocket:MyAlarm alarm = new MyAlarm(webSocket::abort); WebSocket.Listener listener = new WebSocket.Listener() { public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) { alarm.snooze(); ... } ... }; ... Runnable startTimer = () -> { MyTimer idleTimer = new MyTimer(); idleTimer.add(alarm, 30, TimeUnit.SECONDS); }; webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "ok").thenRun(startTimer); - 参数:
-
statusCode- 状态码 -
reason- 原因 - 返回:
-
一个
CompletableFuture,当Close消息已发送时完成,带有此WebSocket
-
request
void request(long n) 增加接收方法调用次数的计数器。此WebSocket将调用关联侦听器(即接收方法)上的
onText、onBinary、onPing、onPong或onClose方法,最多n次。- API注释:
-
此方法的参数是从此WebSocket请求到关联侦听器的调用次数,而不是消息的数量。有时消息可能在单个调用中传递给侦听器,但并非总是如此。例如,Ping、Pong和Close消息分别在
onPing、onPong和onClose方法的单个调用中传递。但是,文本和二进制消息是否在onText和onBinary方法的单个调用中传递取决于这些方法的布尔参数(last)。如果last为false,则消息中还有更多内容未传递给调用。以下是一个请求逐个调用直到积累完整消息,然后处理结果的侦听器示例:
WebSocket.Listener listener = new WebSocket.Listener() { StringBuilder text = new StringBuilder(); public CompletionStage<?> onText(WebSocket webSocket, CharSequence message, boolean last) { text.append(message); if (last) { processCompleteTextMessage(text); text = new StringBuilder(); } webSocket.request(1); return null; } }; - 参数:
-
n- 调用次数 - 抛出:
-
IllegalArgumentException- 如果n <= 0
-
getSubprotocol
String getSubprotocol()返回此WebSocket使用的子协议。- 返回:
- 子协议,如果没有子协议则为空字符串
-
isOutputClosed
boolean isOutputClosed()告知此WebSocket的输出是否已关闭。如果此方法返回
true,随后的调用也将返回true。- 返回:
-
如果关闭则为
true,否则为false
-
isInputClosed
boolean isInputClosed()告知此WebSocket的输入是否已关闭。如果此方法返回
true,随后的调用也将返回true。- 返回:
-
如果关闭则为
true,否则为false
-
abort
void abort()突然关闭此WebSocket的输入和输出。当此方法返回时,输入和输出将都已关闭。任何待处理的发送操作将失败,并显示
IOException。随后对abort的调用将不起作用。
-