Reputation: 54
I'm switching from an undertow WebSocket client, which worked perfectly, to the [built-in implementation available from Java 11]. The connection with the WebSocket is successful, though, after the first message is sent, a SocketException is thrown because of a connection reset. As noted by the documentation, SocketExceptions are usually thrown because of an invalid protocol. Because of this, I tried to switch from TLSv1.3(theoretically the default in Java 11) to TLSv1.2, but this didn't solve the issue either. Here is a simplified version of my code:
class WebSocketClient implements WebSocket.Listener {
private void openConnection() {
var sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, new SecureRandom());
HttpClient.newBuilder()
.sslContext(sslContext)
.build()
.newWebSocketBuilder()
.header("Origin", "https://web.whatsapp.com")
.header("User-Agent", "some user agent")
.subprotocols("permessage-deflate", "client_max_window_bits")
.connectTimeout(Duration.of(30, ChronoUnit.SECONDS))
.buildAsync(URI.create("wss://web.whatsapp.com/ws"), this);
}
@Override
public void onOpen(WebSocket socket) {
WebSocket.Listener.super.onOpen(socket);
socket.sendText("tag,irrelevantMessage", true);
}
}
I have enabled the debugging feature of the HTTP module and this is the output:
DEBUG: [ForkJoinPool.commonPool-worker-3] [489ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) connectFlows
DEBUG: [ForkJoinPool.commonPool-worker-3] [489ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) ReadSubscriber::onSubscribe
DEBUG: [ForkJoinPool.commonPool-worker-3] [489ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) WritePublisher::subscribe
DEBUG: [ForkJoinPool.commonPool-worker-3] [489ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) WriteSubscription::request 1
DEBUG: [ForkJoinPool.commonPool-worker-3] [494ms] [Transport] write buffer capacity 16384
DEBUG: [ForkJoinPool.commonPool-worker-3] [495ms] [WebSocket] signalOpen
DEBUG: [ForkJoinPool.commonPool-worker-3] [495ms] [WebSocket] enter receive task
DEBUG: [ForkJoinPool.commonPool-worker-3] [495ms] [WebSocket] receive state: OPEN
DEBUG: [ForkJoinPool.commonPool-worker-3] [495ms] [WebSocket] enter onOpen 1
DEBUG: [ForkJoinPool.commonPool-worker-3] [495ms] [WebSocket] request 1
DEBUG: [ForkJoinPool.commonPool-worker-3] [502ms] [WebSocket] enter send text 1 payload length=124 last=true
DEBUG: [ForkJoinPool.commonPool-worker-3] [502ms] [Transport] enter send text 1 message.length=124 last=true
DEBUG: [ForkJoinPool.commonPool-worker-3] [502ms] [Transport] enter send task
DEBUG: [ForkJoinPool.commonPool-worker-3] [502ms] [Transport] load message
DEBUG: [ForkJoinPool.commonPool-worker-3] [502ms] [Output] encode text src=[pos=0 lim=124 cap=124] last=true dst=java.nio.HeapByteBuffer[pos=0 lim=16384 cap=16384]
DEBUG: [ForkJoinPool.commonPool-worker-3] [502ms] [Output] put
DEBUG: [ForkJoinPool.commonPool-worker-3] [503ms] [Output] mask
DEBUG: [ForkJoinPool.commonPool-worker-3] [503ms] [Output] moreText
DEBUG: [ForkJoinPool.commonPool-worker-3] [503ms] [Output] frame #0
DEBUG: [ForkJoinPool.commonPool-worker-3] [503ms] [Output] frame opcode=TEXT fin=true len=124
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Output] put
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Output] mask
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Output] moreText
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Transport] enter writing
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Transport] write state: UNREGISTERED
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Transport] registering write event
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) register write event
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Transport] write event
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Transport] registered write event
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Transport] exit writing
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Transport] exit send task
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Transport] enter send task
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Transport] 130 bytes remaining in buffer java.nio.HeapByteBuffer[pos=0 lim=130 cap=16384]
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Transport] enter writing
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Transport] write state: AVAILABLE
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [Transport] writing to the channel
DEBUG: [ForkJoinPool.commonPool-worker-3] [504ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) write: writing 130
DEBUG: [ForkJoinPool.commonPool-worker-3] [505ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) WriteSubscription::request 1
DEBUG: [ForkJoinPool.commonPool-worker-3] [505ms] [Transport] 130 bytes written
DEBUG: [ForkJoinPool.commonPool-worker-3] [505ms] [Transport] finished writing to the channel
DEBUG: [ForkJoinPool.commonPool-worker-3] [505ms] [Transport] exit writing
DEBUG: [ForkJoinPool.commonPool-worker-3] [505ms] [Transport] removeAndComplete error=null
DEBUG: [ForkJoinPool.commonPool-worker-3] [505ms] [Transport] exit send task
DEBUG: [ForkJoinPool.commonPool-worker-3] [506ms] [Transport] exit send text 1 returned jdk.internal.net.http.common.MinimalFuture@5c97152e[Completed normally] (id=63)
DEBUG: [ForkJoinPool.commonPool-worker-3] [506ms] [WebSocket] exit send text 1 returned jdk.internal.net.http.common.MinimalFuture@5c97152e[Completed normally] (id=63)
DEBUG: [ForkJoinPool.commonPool-worker-3] [508ms] [WebSocket] exit onOpen 1
DEBUG: [ForkJoinPool.commonPool-worker-3] [508ms] [WebSocket] change state from OPEN to IDLE true
DEBUG: [ForkJoinPool.commonPool-worker-3] [508ms] [WebSocket] receive state: IDLE
DEBUG: [ForkJoinPool.commonPool-worker-3] [508ms] [WebSocket] change state from IDLE to WAITING true
DEBUG: [ForkJoinPool.commonPool-worker-3] [508ms] [Transport] request 1
DEBUG: [ForkJoinPool.commonPool-worker-3] [508ms] [Transport] enter receive task
DEBUG: [ForkJoinPool.commonPool-worker-3] [508ms] [Transport] receive state: UNREGISTERED
DEBUG: [ForkJoinPool.commonPool-worker-3] [508ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) register read event
DEBUG: [ForkJoinPool.commonPool-worker-3] [509ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) readSubscription: requesting 1
DEBUG: [ForkJoinPool.commonPool-worker-3] [509ms] [Transport] exit receive task
DEBUG: [ForkJoinPool.commonPool-worker-3] [509ms] [WebSocket] exit receive task
DEBUG: [ForkJoinPool.commonPool-worker-3] [509ms] [WebSocket] enter receive task
DEBUG: [ForkJoinPool.commonPool-worker-3] [509ms] [WebSocket] receive state: WAITING
DEBUG: [ForkJoinPool.commonPool-worker-3] [509ms] [WebSocket] exit receive task
DEBUG: [HttpClient-1-SelectorManager] [510ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) ReadSubscriber::onError java.net.SocketException: Connection reset
java.net.SocketException: Connection reset
at java.base/sun.nio.ch.SocketChannelImpl.throwConnectionReset(SocketChannelImpl.java:394)
at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:426)
at java.net.http/jdk.internal.net.http.SocketTube.readAvailable(SocketTube.java:1162)
at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$InternalReadSubscription.read(SocketTube.java:825)
at java.net.http/jdk.internal.net.http.SocketTube$SocketFlowTask.run(SocketTube.java:175)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:271)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:224)
at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$InternalReadSubscription.signalReadable(SocketTube.java:766)
at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$ReadEvent.signalEvent(SocketTube.java:949)
at java.net.http/jdk.internal.net.http.SocketTube$SocketFlowEvent.handle(SocketTube.java:245)
at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.handleEvent(HttpClientImpl.java:960)
at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.lambda$run$3(HttpClientImpl.java:915)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.run(HttpClientImpl.java:915)
DEBUG: [HttpClient-1-SelectorManager] [511ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) ReadSubscriber: handling event
DEBUG: [HttpClient-1-SelectorManager] [511ms] [Transport] read event
DEBUG: [HttpClient-1-SelectorManager] [511ms] [Transport] enter receive task
DEBUG: [HttpClient-1-SelectorManager] [511ms] [Transport] receive state: AVAILABLE
DEBUG: [HttpClient-1-SelectorManager] [511ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) read
DEBUG: [HttpClient-1-SelectorManager] [511ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) read: java.net.SocketException: Connection reset
DEBUG: [HttpClient-1-SelectorManager] [511ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) shutdownInput
DEBUG: [HttpClient-1-SelectorManager] [511ms] [WebSocket] signalError java.net.SocketException: Connection reset
DEBUG: [HttpClient-1-SelectorManager] [511ms] [WebSocket] enter receive task
DEBUG: [HttpClient-1-SelectorManager] [511ms] [WebSocket] receive state: ERROR
DEBUG: [HttpClient-1-SelectorManager] [511ms] [WebSocket] processError
DEBUG: [HttpClient-1-SelectorManager] [511ms] [Transport] closeInput
DEBUG: [HttpClient-1-SelectorManager] [511ms] [WebSocket] enter onError 2 error=java.net.SocketException: Connection reset
DEBUG: [HttpClient-1-SelectorManager] [511ms] [WebSocket] exit onError 2
DEBUG: [HttpClient-1-SelectorManager] [511ms] [WebSocket] signalError java.lang.RuntimeException: An unhandled exception was registered during the lifecycle of this session
DEBUG: [HttpClient-1-SelectorManager] [511ms] [WebSocket] signalError java.lang.RuntimeException: An unhandled exception was registered during the lifecycle of this session
java.lang.RuntimeException: An unhandled exception was registered during the lifecycle of this session
at whatsapp4j/it.auties.whatsapp4j.whatsapp.WhatsappWebSocket.onError(WhatsappWebSocket.java:212)
at java.net.http/jdk.internal.net.http.websocket.WebSocketImpl$ReceiveTask.processError(WebSocketImpl.java:500)
at java.net.http/jdk.internal.net.http.websocket.WebSocketImpl$ReceiveTask.run(WebSocketImpl.java:454)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:271)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:224)
at java.net.http/jdk.internal.net.http.websocket.WebSocketImpl.trySetState(WebSocketImpl.java:837)
at java.net.http/jdk.internal.net.http.websocket.WebSocketImpl.signalError(WebSocketImpl.java:714)
at java.net.http/jdk.internal.net.http.websocket.WebSocketImpl$SignallingMessageConsumer.onError(WebSocketImpl.java:825)
at java.net.http/jdk.internal.net.http.websocket.TransportImpl$ReceiveTask.run(TransportImpl.java:704)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:271)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:224)
at java.net.http/jdk.internal.net.http.websocket.TransportImpl$ReadEvent.handle(TransportImpl.java:766)
at java.net.http/jdk.internal.net.http.RawChannelTube$ReadSubscriber.checkEvents(RawChannelTube.java:174)
at java.net.http/jdk.internal.net.http.RawChannelTube$ReadSubscriber.onError(RawChannelTube.java:212)
at java.net.http/jdk.internal.net.http.common.SSLTube$DelegateWrapper.onError(SSLTube.java:257)
at java.net.http/jdk.internal.net.http.common.SSLTube$SSLSubscriberWrapper.complete(SSLTube.java:441)
at java.net.http/jdk.internal.net.http.common.SSLTube$SSLSubscriberWrapper.onErrorImpl(SSLTube.java:511)
at java.net.http/jdk.internal.net.http.common.SSLTube$SSLSubscriberWrapper.onError(SSLTube.java:525)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher.run1(SubscriberWrapper.java:294)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher.run(SubscriberWrapper.java:259)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:271)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:224)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper.errorCommon(SubscriberWrapper.java:419)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.errorCommon(SSLFlowDelegate.java:366)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper.onError(SubscriberWrapper.java:410)
at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$ReadSubscription.signalCompletion(SocketTube.java:629)
at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$InternalReadSubscription.read(SocketTube.java:813)
at java.net.http/jdk.internal.net.http.SocketTube$SocketFlowTask.run(SocketTube.java:175)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:271)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:224)
at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$InternalReadSubscription.signalReadable(SocketTube.java:766)
at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$ReadEvent.signalEvent(SocketTube.java:949)
at java.net.http/jdk.internal.net.http.SocketTube$SocketFlowEvent.handle(SocketTube.java:245)
at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.handleEvent(HttpClientImpl.java:960)
at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.lambda$run$3(HttpClientImpl.java:915)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.run(HttpClientImpl.java:915)
Caused by: java.net.SocketException: Connection reset
at java.base/sun.nio.ch.SocketChannelImpl.throwConnectionReset(SocketChannelImpl.java:394)
at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:426)
at java.net.http/jdk.internal.net.http.SocketTube.readAvailable(SocketTube.java:1162)
at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$InternalReadSubscription.read(SocketTube.java:825)
... 11 more
DEBUG: [HttpClient-1-SelectorManager] [512ms] [WebSocket] exit receive task
DEBUG: [HttpClient-1-SelectorManager] [512ms] [WebSocket] set state ERROR (previous WAITING) true
DEBUG: [HttpClient-1-SelectorManager] [512ms] [WebSocket] close
DEBUG: [HttpClient-1-SelectorManager] [512ms] [Transport] closeInput
DEBUG: [HttpClient-1-SelectorManager] [512ms] [Transport] closeOutput
DEBUG: [HttpClient-1-SelectorManager] [512ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) shutdownOutput
DEBUG: [HttpClient-1-SelectorManager] [512ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) close
DEBUG: [HttpClient-1-SelectorManager] [512ms] [Transport] enter send task
DEBUG: [HttpClient-1-SelectorManager] [512ms] [Transport] exit send task
DEBUG: [HttpClient-1-SelectorManager] [512ms] [Transport] exit receive task
DEBUG: [HttpClient-1-SelectorManager] [512ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) WriteSubscription::cancel
Update:
As suggested in the comments, I've modified my code and now the exception's message is "Connection reset by peer" instead of "Connection reset". These are the new logs:
DEBUG: [ForkJoinPool.commonPool-worker-3] [333ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) connectFlows
DEBUG: [ForkJoinPool.commonPool-worker-3] [333ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) ReadSubscriber::onSubscribe
DEBUG: [ForkJoinPool.commonPool-worker-3] [333ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) WritePublisher::subscribe
DEBUG: [ForkJoinPool.commonPool-worker-3] [333ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) WriteSubscription::request 1
DEBUG: [ForkJoinPool.commonPool-worker-3] [336ms] [Transport] write buffer capacity 16384
DEBUG: [ForkJoinPool.commonPool-worker-3] [337ms] [WebSocket] signalOpen
DEBUG: [ForkJoinPool.commonPool-worker-3] [337ms] [WebSocket] enter receive task
DEBUG: [ForkJoinPool.commonPool-worker-3] [337ms] [WebSocket] receive state: OPEN
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [WebSocket] enter onOpen 1
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [WebSocket] request 1
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [WebSocket] exit onOpen 1
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [WebSocket] change state from OPEN to IDLE true
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [WebSocket] receive state: IDLE
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [WebSocket] change state from IDLE to WAITING true
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [Transport] request 1
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [Transport] enter receive task
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [Transport] receive state: UNREGISTERED
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) register read event
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) readSubscription: requesting 1
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [Transport] exit receive task
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [WebSocket] exit receive task
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [WebSocket] enter receive task
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [WebSocket] receive state: WAITING
DEBUG: [ForkJoinPool.commonPool-worker-3] [338ms] [WebSocket] exit receive task
DEBUG: [ForkJoinPool.commonPool-worker-3] [339ms] [WebSocket] enter send binary 1 payload=java.nio.HeapByteBuffer[pos=0 lim=0 cap=0] last=true
DEBUG: [ForkJoinPool.commonPool-worker-3] [339ms] [Transport] enter send binary 1 message.remaining=0 last=true
DEBUG: [ForkJoinPool.commonPool-worker-3] [339ms] [Transport] enter send task
DEBUG: [ForkJoinPool.commonPool-worker-3] [339ms] [Transport] load message
DEBUG: [ForkJoinPool.commonPool-worker-3] [339ms] [Output] encode binary src=java.nio.HeapByteBuffer[pos=0 lim=0 cap=0] last=true dst=java.nio.HeapByteBuffer[pos=0 lim=16384 cap=16384]
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [Output] frame opcode=BINARY fin=true len=0
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [Transport] enter writing
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [Transport] write state: UNREGISTERED
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [Transport] registering write event
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) register write event
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [Transport] write event
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [Transport] registered write event
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [Transport] exit writing
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [Transport] exit send task
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [Transport] enter send task
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [Transport] 6 bytes remaining in buffer java.nio.HeapByteBuffer[pos=0 lim=6 cap=16384]
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [Transport] enter writing
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [Transport] write state: AVAILABLE
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [Transport] writing to the channel
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) write: writing 6
DEBUG: [ForkJoinPool.commonPool-worker-3] [340ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) WriteSubscription::request 1
DEBUG: [ForkJoinPool.commonPool-worker-3] [341ms] [Transport] 6 bytes written
DEBUG: [ForkJoinPool.commonPool-worker-3] [341ms] [Transport] finished writing to the channel
DEBUG: [ForkJoinPool.commonPool-worker-3] [341ms] [Transport] exit writing
DEBUG: [ForkJoinPool.commonPool-worker-3] [341ms] [Transport] removeAndComplete error=null
DEBUG: [ForkJoinPool.commonPool-worker-3] [341ms] [Transport] exit send task
DEBUG: [ForkJoinPool.commonPool-worker-3] [342ms] [Transport] exit send binary 1 returned jdk.internal.net.http.common.MinimalFuture@2750fa5d[Completed normally] (id=64)
DEBUG: [ForkJoinPool.commonPool-worker-3] [342ms] [WebSocket] exit send binary 1 returned jdk.internal.net.http.common.MinimalFuture@2750fa5d[Completed normally] (id=64)
DEBUG: [HttpClient-1-Worker-0] [344ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) WriteSubscription::cancel
DEBUG: [HttpClient-1-Worker-0] [344ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) shutdownOutput
DEBUG: [HttpClient-1-Worker-0] [345ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) ReadSubscriber::onError java.io.IOException: Connection reset by peer
java.io.IOException: Connection reset by peer
at java.base/sun.nio.ch.SocketDispatcher.writev0(Native Method)
at java.base/sun.nio.ch.SocketDispatcher.writev(SocketDispatcher.java:58)
at java.base/sun.nio.ch.IOUtil.write(IOUtil.java:182)
at java.base/sun.nio.ch.IOUtil.write(IOUtil.java:130)
at java.base/sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:563)
at java.base/java.nio.channels.SocketChannel.write(SocketChannel.java:642)
at java.net.http/jdk.internal.net.http.SocketTube.writeAvailable(SocketTube.java:1228)
at java.net.http/jdk.internal.net.http.SocketTube$InternalWriteSubscriber.tryFlushCurrent(SocketTube.java:342)
at java.net.http/jdk.internal.net.http.SocketTube$InternalWriteSubscriber.onNext(SocketTube.java:309)
at java.net.http/jdk.internal.net.http.SocketTube.onNext(SocketTube.java:133)
at java.net.http/jdk.internal.net.http.SocketTube.onNext(SocketTube.java:56)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher.run1(SubscriberWrapper.java:316)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher.run(SubscriberWrapper.java:259)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:271)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:224)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper.outgoing(SubscriberWrapper.java:232)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper.outgoing(SubscriberWrapper.java:198)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Writer.sendResultBytes(SSLFlowDelegate.java:934)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Writer.processData(SSLFlowDelegate.java:817)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Writer$WriterDownstreamPusher.run(SSLFlowDelegate.java:694)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:271)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:224)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Writer.triggerWrite(SSLFlowDelegate.java:771)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.doHandshake(SSLFlowDelegate.java:1083)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.doClosure(SSLFlowDelegate.java:1169)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.unwrapBuffer(SSLFlowDelegate.java:549)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:433)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:268)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base/java.lang.Thread.run(Thread.java:831)
DEBUG: [HttpClient-1-Worker-0] [345ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) ReadSubscriber: handling event
DEBUG: [HttpClient-1-Worker-0] [345ms] [Transport] read event
DEBUG: [HttpClient-1-Worker-0] [345ms] [Transport] enter receive task
DEBUG: [HttpClient-1-Worker-0] [345ms] [Transport] receive state: AVAILABLE
DEBUG: [HttpClient-1-Worker-0] [345ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) read
DEBUG: [HttpClient-1-Worker-0] [345ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) read: java.io.IOException: Connection reset by peer
DEBUG: [HttpClient-1-Worker-0] [345ms] [WebSocket] RawChannelTube(SSLTube(SocketTube(1))) shutdownInput
DEBUG: [HttpClient-1-Worker-0] [346ms] [WebSocket] signalError java.io.IOException: Connection reset by peer
DEBUG: [HttpClient-1-Worker-0] [346ms] [WebSocket] enter receive task
DEBUG: [HttpClient-1-Worker-0] [346ms] [WebSocket] receive state: ERROR
DEBUG: [HttpClient-1-Worker-0] [346ms] [WebSocket] processError
DEBUG: [HttpClient-1-Worker-0] [346ms] [Transport] closeInput
DEBUG: [HttpClient-1-Worker-0] [346ms] [WebSocket] enter onError 2 error=java.io.IOException: Connection reset by peer
DEBUG: [HttpClient-1-Worker-0] [346ms] [WebSocket] exit onError 2
I've also reproduced the same piece of code using JakartaEE 9.1 and it seems to work perfectly
@ClientEndpoint(configurator = ClientTest.class)
public class ClientTest extends ClientEndpointConfig.Configurator {
public void openConnection() throws DeploymentException, IOException {
var session = createSession();
session.getBasicRemote().sendText("tag,irrelevantMessage");
}
private Session createSession() throws DeploymentException, IOException {
return ContainerProvider.getWebSocketContainer().connectToServer(this, URI.create("wss://web.whatsapp.com/ws"));
}
@OnMessage
public void onTextMessage(String message){
System.out.println(message);
}
@Override
public void beforeRequest(Map<String, List<String>> headers) {
headers.put("Origin", List.of("https://web.whatsapp.com"));
}
}
Even sending an empty binary message will throw an equivalent exception
Upvotes: 1
Views: 2501
Reputation: 6736
Please try without the timeout parameter .connectTimeout(Duration.of(30, ChronoUnit.SECONDS))
...
class WebSocketClient implements WebSocket.Listener {
private void openConnection() {
var sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, new SecureRandom());
HttpClient.newBuilder()
.sslContext(sslContext)
.build()
.newWebSocketBuilder()
.header("Origin", "https://web.whatsapp.com")
.header("User-Agent", "some user agent")
.subprotocols("permessage-deflate", "client_max_window_bits")
.buildAsync(URI.create("wss://web.whatsapp.com/ws"), this);
}
@Override
public void onOpen(WebSocket socket) {
WebSocket.Listener.super.onOpen(socket);
socket.sendText("tag,irrelevantMessage", true);
}
}
Upvotes: 1