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的主要内容,如果未能解决你的问题,请参考以下文章

为啥eclipse启动tomcat登录不了localhost:8080

MyEclipse异常关闭导致Tomcat不能启动的问题

Tomcat之端口占用问题的解决

(转)WebSocket学习

tomcat里的chat例子websocket连不上

我可以在同一台机器上运行两个 tomcat 实例吗?