Java WebSockets: Le point de terminaison distant était en état [TEXT_FULL_WRITING]
Je suis en train de mettre en œuvre une application basée sur les websockets qui permettra de communiquer avec JS clients assez intensivement.
Le code pour envoyer le message est assez primitif:
synchronized (session) {
if (session.isOpen()) {
session.getBasicRemote().sendText(message);
}
}
Pour rare envoi il fonctionne très bien, mais quand quelques threads tentent d'envoyer des messages par la même session (socket), l'exception suivante est levée (veuillez noter qu'il n'est pas le multithreading question, car le bloc de code est synchronisé par session):
java.lang.IllegalStateException: The remote endpoint was in state [TEXT_FULL_WRITING] which is an invalid state for called method
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.checkState(WsRemoteEndpointImplBase.java:1015)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.textStart(WsRemoteEndpointImplBase.java:978)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendString(WsRemoteEndpointImplBase.java:161)
at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendText(WsRemoteEndpointBasic.java:37)
Google n'est pas riche de ce type d'exceptions en ce moment et après avoir battu quelques heures sur ce problème, toujours pas de solution.
Java 7.0.21, testé sur Tomcat 7.0.52 et Tomcat 8.0.3.
Toute réponse est très apprécié!
Merci à l'avance.
Mise à JOUR 3/11/2014: j'ai testé ma demande avec Jetty 9.1 et cette exception n'a pas eu lieu.
Je suppose que c'est Tomcat mise en œuvre de bug.
OriginalL'auteur walv | 2014-03-07
Vous devez vous connecter pour publier un commentaire.
OK, ce n'est pas un Tomcat question, mais de ma faute.
Mon onMessage fonction renvoyées une chaîne de caractères, ce qui signifie que j'ai fait l'écho du message de retour. Comme conséquence, la partie de code n'a pas été synchronisé.
Mauvais:
Bon:
parce que "le message de retour" dans la méthode "onMessage" est égal à "session.getBasicRemote().sendText(message);". Comme résultat, vous ne pouvez pas synchroniser la valeur de retour de la méthode spécifique de verrouillage de l'instance. En d'autres termes, la valeur de retour n'est pas dans votre synchronisation de bloc. Donc le mieux est d'envoyer le message via la méthode de la valeur de retour, mais par l'intermédiaire de "session.getBasicRemote().sendText(message);" ce qui est sous votre synchronisation contrôle. Espérons que cela aide.
j'ai cette erreur lors de la sendText (beaucoup de texte - les journaux), mais pas de onMessage est appelé pendant ce temps.
simple, direct à l'essentiel, je vous remercie.
OriginalL'auteur walv
J'ai trouvé ceci: https://bz.apache.org/bugzilla/show_bug.cgi?id=56026
semble tomcat a fait quelque chose d'inattendu, comme une solution de contournement, vous devez synchroniser l'ensemble de la session.sendxxx appels, peu importe s'il est asynchrone.
OriginalL'auteur user4359767