1
votes

Hi guys am getting following error am using Websocket and Tomcat8.

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:1092)
    at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.textStart(WsRemoteEndpointImplBase.java:1055)
    at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendString(WsRemoteEndpointImplBase.java:186)
    at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendText(WsRemoteEndpointBasic.java:37)
    at com.iri.monitor.webSocket.IRIMonitorSocketServlet.broadcastData(IRIMonitorSocketServlet.java:369)
    at com.iri.monitor.webSocket.IRIMonitorSocketServlet.access$0(IRIMonitorSocketServlet.java:356)
    at com.iri.monitor.webSocket.IRIMonitorSocketServlet$5.run(IRIMonitorSocketServlet.java:279)
3
So then you do that engineering thing called research, which in this case starts with copy/pasting that error into google. Not surprisingly, the search result list is not empty and includes existing stack overflow questions such as this one: stackoverflow.com/questions/22257079/… - Gimby
It means you are trying to write to a websocket while the previous message has not finished transferring. So thus it causes an exception. - jgr208
Looks like that this is tomcat behaviour as mentioned in this bug report: bz.apache.org/bugzilla/show_bug.cgi?id=56026 - kaptan

3 Answers

3
votes

You are trying to write to a websocket that is not in a ready state. The websocket is currently in writing mode and you are trying to write another message to that websocket which raises an error. Using an async write or as not such good practice a sleep can prevent this from happening. This error is also normally raised when a websocket program is not thread safe.

0
votes

Neither async or sleep can help.

The key problem is the send-method can not be called concurrently.

So it's just about concurrency, you can use locks or some other thing. Here is how I handle it.

In fact, I write a actor to wrap the socketSession. It will produce an event when the send-method is called. Each actor will be registered in an Looper which contains a work thread and an event queue. Meanwhile the work thread keeps sending message.

So, I will use the sync-send method inside, the actor model will make sure about the concurrency.

The key problem now is about the number of Looper. You know, you can't make neither too much or too few threads. But you can still estimate a number by your business cases, and keep adjusting it.

0
votes

it is actually not a concurrency issue, you will have the same error in a single-threaded environment. It is about asynchronous calls that must not overlap.

You should use session.get**Basic**Remote().sendText instead of session.get**Async**Remote().sendText() to avoid this problem. Should not be an issue as long as the amount of data you are writing stays reasonable small.