2015-03-12 29 views
8

Sto usando tomcat 8.0.15, primavera 4.1.5.WebSocket L'endpoint remoto era nello stato [TEXT_PARTIAL_WRITING]

Ho implementato 3 funzioni obbligatorie per l'utilizzo di websocket come di seguito. È molto semplice.

Alcuni client inviano un messaggio e altri client ottengono il messaggio tramite handleTextMessage.

Nel mio caso, senza la funzione handleTextMessage, il programma server vuole inviare un messaggio di testo ai client. (per questo ho salvato di un WebSocketSession Id e nome utente in MAP_ID)

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

Sopra codice funziona molto bene. Ma quando WebSocketSession di alcuni client è in uso e tenta di usare simultaneamente, commette un errore. Significa 1. un client invia un messaggio -> handleTextMessage viene chiamato -> il client WebSocketSession utilizza 2. il programma del server vuole inviare un messaggio a quel client -> ottenere la WebSocketSession del client dalla mappa -> provare a inviare il messaggio con lo stesso 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) 

Come risultato, WebSocketSession viene chiusa e il client deve aprire di nuovo nuova WebSocketSession.

Quindi, la mia domanda è:

posso verificare se il WebSocketSession è in uso o no? (fuori funzione handleTextMessage)

risposta

11

Il problema è che molti filo prova a scrivere in contemporaneamente sulla presa così:

prova:

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

Durante la sincronizzazione sendMessage() chiamate aiuta per WS:// connessione, non aiuta per wss://, i.e. SSL/TLS connection. È un fallimento del 100% se si tenta di inviare messaggi parziali durante la lettura di messaggi parziali. L'ho provato su Spring Boot 1.4.2 RELEASE (tomcat 8.5.6)

Lo stesso con tomcat 8.5.9. Vedi la pila di traccia qui sotto.

[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], 
Problemi correlati