WebSocket 远程端点处于状态 [TEXT_PARTIAL_WRITING]

我用 tomcat 8.0.15, spring 4.1.5.

我实施了 3 强制性的使用功能 websocket, 如下所示。
一切都很简单。


private Map<string, websocketsession=""> map_users = new ConcurrentHashMap&lt;&gt;//;
private Map<string, string=""> map_id = new ConcurrentHashMap&lt;&gt;//;

public void afterConnectionEstablished/WebSocketSession wss/ throws Exception {
map_users.put/wss.getId//, wss/;
}

public void afterConnectionClosed/WebSocketSession wss, CloseStatus cs/ throws Exception {
map_users.remove/wss.getId///;

// remove user
String username = map_id.get/wss.getId///;
if /username != null/ {
map_id.remove/wss.getId///;
map_id.remove/username/;
}
}

public void handleTextMessage/WebSocketSession wss, TextMessage tm/ throws Exception {
String str = tm.getPayload//;
String username = ...;

// regist user
if /!map_id.get/wss.getId//// {
map_id.put/wss.getId//, username/;
map_id.put/username, wss.getId///;
}

for /WebSocketSession w: map_users.values/// {
w.sendMessage/new TextMessage/wss.getId// + " send to " + w.getId// + ", msg:" + tm.getPayload////;
}
}


一个客户端发消息,其他客户接收邮件 handleTextMessage.

在我的情况下,没有函数 handleTextMessage, 服务器程序希望向客户发送短信。
/为此,我保存了标识符 WebSocketSession 和用户名 map_id/


String websocketsesssion_id = map_id.get/username/;
WebSocketSession wss = map_users.get/websocketsesssion_id/;
wss.sendMessage/new TextMessage/new java.util.Date////;


上面的代码非常好。
但是当一些客户端 WebSocketSession 使用并尝试同时使用,犯了一个错误。
它的意思是
1. 有些客户发送消息 --&gt; handleTextMessage 叫 --&gt; 客户 WebSocketSession 用途
2. 服务器程序希望向此客户端发送消息 -&gt; 收到 WebSocketSession 客户带地图 -&gt; 尝试使用相同的消息发送消息 WebSocketSession


Stacktrace:] with root cause
java.lang.IllegalStateException: The remote endpoint was in state [TEXT_PARTIAL_WRITING] which is an invalid state for called method
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.checkState/WsRemoteEndpointImplBase.java:1092/
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.textPartialStart/WsRemoteEndpointImplBase.java:1050/
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendPartialString/WsRemoteEndpointImplBase.java:218/
at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendText/WsRemoteEndpointBasic.java:49/
at org.springframework.web.socket.adapter.standard.StandardWebSocketSession.sendTextMessage/StandardWebSocketSession.java:197/
at org.springframework.web.socket.adapter.AbstractWebSocketSession.sendMessage/AbstractWebSocketSession.java:105/
at org.springframework.web.socket.sockjs.transport.session.WebSocketServerSockJsSession.writeFrameInternal/WebSocketServerSockJsSession.java:222/
at org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession.writeFrame/AbstractSockJsSession.java:325/
at org.springframework.web.socket.sockjs.transport.session.WebSocketServerSockJsSession.sendMessageInternal/WebSocketServerSockJsSession.java:212/
at org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession.sendMessage/AbstractSockJsSession.java:161/


因此 WebSocketSession 关闭,客户必须打开一个新的 WebSocketSession.

所以,我的问题是:

我可以检查它是否使用 WebSocketSession 或不?
/在功能之外 handleTextMessage/
</string,></string,>
已邀请:

二哥

赞同来自:

问题是,几条流在套接字上同时写入,所以 :

样本 :


String websocketsesssion_id = map_id.get/username/;
WebSocketSession wss = map_users.get/websocketsesssion_id/;
synchronized/wss/ {
wss.sendMessage/new TextMessage/new java.util.Date////;
}

郭文康

赞同来自:

虽然呼叫同步
sendMessage//

有助于连接 ws://, 它没有帮助
wss://, i.e. SSL/TLS connection

. 它 100% 如果您尝试在阅读部分消息时发送部分消息,则失败。 我检查了它 Spring Boot 1.4.2 RELEASE /tomcat 8.5.6/

与此同样 tomcat 8.5.9. 见堆栈 trace 以下。


[pool-18-thread-1] [GenericMessageEndpoint] Sending message to the endpoint: 
[pool-18-thread-2] [GenericMessageEndpoint] Sending message to the endpoint:
[pool-18-thread-3] [GenericMessageEndpoint] Sending message to the endpoint:

[https-jsse-nio-8443-exec-1] [FrontendWebSocketHandler] Message from 0, isLast: false, length: 16384
[https-jsse-nio-8443-exec-1] [FrontendWebSocketHandler] Message from 0, isLast: false, length: 16384

[pool-18-thread-3] [FrontendWebSocketHandler] Transport error. Session: StandardWebSocketSession[id=0, uri=/myt/websocket]
java.io.IOException: java.io.IOException: Unable to wrap data, invalid status [CLOSED]
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock/WsRemoteEndpointImplBase.java:315/
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock/WsRemoteEndpointImplBase.java:258/
at org.apache.tomcat.websocket.WsSession.sendCloseMessage/WsSession.java:606/
at org.apache.tomcat.websocket.WsSession.doClose/WsSession.java:494/
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock/WsRemoteEndpointImplBase.java:313/
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock/WsRemoteEndpointImplBase.java:250/
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendPartialString/WsRemoteEndpointImplBase.java:223/
at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendText/WsRemoteEndpointBasic.java:49/
at org.springframework.web.socket.adapter.standard.StandardWebSocketSession.sendTextMessage/StandardWebSocketSession.java:197/
at org.springframework.web.socket.adapter.AbstractWebSocketSession.sendMessage/AbstractWebSocketSession.java:104/
at com.ebs.mytreasury.frontend.websocket.FrontendWebSocketHandler.send/FrontendWebSocketHandler.java:180/
at com.ebs.mytreasury.frontend.websocket.FrontendWebSocketHandler.send/FrontendWebSocketHandler.java:24/
at com.ebs.mytreasury.frontend.GenericMessageEndpoint.sendMessage/GenericMessageEndpoint.java:72/
at com.ebs.mytreasury.frontend.GenericMessageEndpoint.send/GenericMessageEndpoint.java:57/
at com.mytreasury.services.backend.MessageSender.process/MessageSender.java:24/
at com.mytreasury.services.backend.AbstractTopicMessageHandler.handle/AbstractTopicMessageHandler.java:47/
at com.mytreasury.services.backend.AbstractTopicMessageHandler.handle/AbstractTopicMessageHandler.java:52/
at com.mytreasury.services.backend.AbstractTopicMessageHandler.handle/AbstractTopicMessageHandler.java:52/
at com.mytreasury.services.backend.AbstractTopicMessageHandler.handle/AbstractTopicMessageHandler.java:52/
at com.mytreasury.services.backend.AbstractTopicMessageHandler.handle/AbstractTopicMessageHandler.java:52/
at com.mytreasury.services.backend.AbstractTopicMessageHandler.handle/AbstractTopicMessageHandler.java:52/
at com.mytreasury.services.backend.AbstractTopicMessageHandler.handle/AbstractTopicMessageHandler.java:52/
at com.mytreasury.services.backend.AbstractTopicMessageHandler.handle/AbstractTopicMessageHandler.java:52/
at com.mytreasury.services.backend.AbstractTopicMessageHandler.handle/AbstractTopicMessageHandler.java:52/
at com.ebs.mytreasury.frontend.message.handler.ResponseGenericMessageHandler.handle/ResponseGenericMessageHandler.java:52/
at com.ebs.mytreasury.frontend.socket.EventPublisherSocketHandler.handle/EventPublisherSocketHandler.java:96/
at com.ebs.mytreasury.frontend.socket.EventPublisherSocketHandler$1$1.run/EventPublisherSocketHandler.java:135/
at java.util.concurrent.ThreadPoolExecutor.runWorker/ThreadPoolExecutor.java:1142/
at java.util.concurrent.ThreadPoolExecutor$Worker.run/ThreadPoolExecutor.java:617/
at java.lang.Thread.run/Thread.java:745/
Caused by: java.io.IOException: Unable to wrap data, invalid status [CLOSED]
at org.apache.tomcat.util.net.SecureNioChannel.write/SecureNioChannel.java:647/
at org.apache.tomcat.util.net.NioBlockingSelector.write/NioBlockingSelector.java:101/
at org.apache.tomcat.util.net.NioSelectorPool.write/NioSelectorPool.java:157/
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doWrite/NioEndpoint.java:1241/
at org.apache.tomcat.util.net.SocketWrapperBase.doWrite/SocketWrapperBase.java:670/
at org.apache.tomcat.util.net.SocketWrapperBase.flushBlocking/SocketWrapperBase.java:607/
at org.apache.tomcat.util.net.SocketWrapperBase.flush/SocketWrapperBase.java:597/
at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite/WsRemoteEndpointImplServer.java:95/
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart/WsRemoteEndpointImplBase.java:494/
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock/WsRemoteEndpointImplBase.java:309/
... 29 common frames omitted
[https-jsse-nio-8443-exec-3] [FrontendWebSocketHandler] Transport error. Session: StandardWebSocketSession[id=0, uri=/myt/websocket]
javax.net.ssl.SSLException: bad record MAC
at sun.security.ssl.Alerts.getSSLException/Alerts.java:208/
at sun.security.ssl.SSLEngineImpl.fatal/SSLEngineImpl.java:1728/
at sun.security.ssl.SSLEngineImpl.readRecord/SSLEngineImpl.java:981/
at sun.security.ssl.SSLEngineImpl.readNetRecord/SSLEngineImpl.java:907/
at sun.security.ssl.SSLEngineImpl.unwrap/SSLEngineImpl.java:781/
at javax.net.ssl.SSLEngine.unwrap/SSLEngine.java:624/
at org.apache.tomcat.util.net.SecureNioChannel.read/SecureNioChannel.java:563/
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer/NioEndpoint.java:1222/
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer/NioEndpoint.java:1195/
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read/NioEndpoint.java:1168/
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable/WsFrameServer.java:62/
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch/WsHttpUpgradeHandler.java:148/
at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch/UpgradeProcessorInternal.java:54/
at org.apache.coyote.AbstractProcessorLight.process/AbstractProcessorLight.java:53/
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process/AbstractProtocol.java:789/
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun/NioEndpoint.java:1437/
at org.apache.tomcat.util.net.SocketProcessorBase.run/SocketProcessorBase.java:49/
at java.util.concurrent.ThreadPoolExecutor.runWorker/ThreadPoolExecutor.java:1142/
at java.util.concurrent.ThreadPoolExecutor$Worker.run/ThreadPoolExecutor.java:617/
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run/TaskThread.java:61/
at java.lang.Thread.run/Thread.java:745/
Caused by: javax.crypto.BadPaddingException: bad record MAC
at sun.security.ssl.EngineInputRecord.decrypt/EngineInputRecord.java:238/
at sun.security.ssl.SSLEngineImpl.readRecord/SSLEngineImpl.java:974/
... 18 common frames omitted
[pool-18-thread-3] [FrontendWebSocketHandler] Connection closed. Session: StandardWebSocketSession[id=0, uri=/myt/websocket], CloseStatus: CloseStatus[code=1006, reason=Unable to wrap data, invalid status [CLOSED]];
[pool-18-thread-2] [GenericMessageEndpoint] Exception while sending message to the endpoint: java.lang.IllegalStateException: The remote endpoint was in state [TEXT_PARTIAL_WRITING] which is an invalid state for called method,
[pool-18-thread-1] [GenericMessageEndpoint] Exception while sending message to the endpoint: java.lang.IllegalStateException: The remote endpoint was in state [TEXT_PARTIAL_WRITING] which is an invalid state for called method,
[pool-18-thread-3] [GenericMessageEndpoint] Exception while sending message to the endpoint: java.io.IOException: java.io.IOException: Unable to wrap data, invalid status [CLOSED],

帅驴

赞同来自:

反而

TEXT_PARTIAL_READY

会议 websocket 也许已经在

State.TEXT_PARTIAL_WRITING

另一个流,如在此处的代码中所示

https://www.codota.com/web/ass ... L1182

要回复问题请先登录注册