Tomcat websocket 和 java
Posted
技术标签:
【中文标题】Tomcat websocket 和 java【英文标题】:Tomcat websocket and java 【发布时间】:2014-12-18 08:15:25 【问题描述】:大家好,在使用 Websocket 和 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)
【问题讨论】:
然后你做那个叫做研究的工程工作,在这种情况下,首先将那个错误复制/粘贴到谷歌中。毫不奇怪,搜索结果列表不为空,并且包括现有的堆栈溢出问题,例如:***.com/questions/22257079/… 这意味着您正在尝试写入 websocket,而前一条消息尚未完成传输。因此它会导致异常。 看起来这是此错误报告中提到的 tomcat 行为:bz.apache.org/bugzilla/show_bug.cgi?id=56026 【参考方案1】:您正在尝试写入未处于就绪状态的 websocket。 websocket 当前处于写入模式,您正在尝试向该 websocket 写入另一条消息,这会引发错误。使用async
写入或sleep
不是很好的做法可以防止这种情况发生。当 websocket 程序不是线程安全的时,通常也会引发此错误。
【讨论】:
我认为async
不会修复它。看起来这是此错误报告中提到的 tomcat 行为:bz.apache.org/bugzilla/show_bug.cgi?id=56026【参考方案2】:
异步或睡眠都无济于事。
关键问题是send-method不能同时调用。
所以它只是关于并发,你可以使用锁或其他东西。这是我的处理方式。
其实我写了一个actor来包装socketSession。当调用发送方法时,它将产生一个事件。每个参与者都将在一个 Looper 中注册,该 Looper 包含一个工作线程和一个事件队列。同时工作线程不断发送消息。
所以,我会在里面使用sync-send方法,actor模型会确保并发。
现在的关键问题是关于 Looper 的数量。你知道,你不能做太多或太少的线程。但是您仍然可以根据您的业务案例估算一个数字,并不断调整它。
【讨论】:
【参考方案3】:其实不是并发问题,在单线程环境下也会出现同样的错误。这是关于不能重叠的异步调用。
您应该使用session.get**Basic**Remote().sendText
而不是session.get**Async**Remote().sendText()
来避免这个问题。只要您写入的数据量保持合理的小量,就不应该成为问题。
【讨论】:
以上是关于Tomcat websocket 和 java的主要内容,如果未能解决你的问题,请参考以下文章