RT,websocket当并发连接过多时就容易报错:
Websocket Connection Exception:java.lang.IllegalStateException: The remote endpoint was in state [TEXT_FULL_WRITING] which is an invalid state for called method
Wepsocket Close Connection:userid_ocnBnw9i4CRxXLiFvNZEq0yNb7-8
Jan 12, 2017 3:14:54 PM org.apache.tomcat.websocket.pojo.PojoEndpointBase onClose
SEVERE: Failed to call onClose method of POJO end point for POJO of type [cn.pxzs.train.websocket.ShakeWapSocket]
java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor35.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.tomcat.websocket.pojo.PojoEndpointBase.onClose(PojoEndpointBase.java:107)
at org.apache.tomcat.websocket.WsSession.fireEndpointOnClose(WsSession.java:514)
at org.apache.tomcat.websocket.WsSession.onClose(WsSession.java:496)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.close(WsHttpUpgradeHandler.java:184)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.access$200(WsHttpUpgradeHandler.java:47)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:206)
at org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:203)
at org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:93)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:621)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1756)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1715)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: 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:1206)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.textStart(WsRemoteEndpointImplBase.java:1169)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendStringByCompletion(WsRemoteEndpointImplBase.java:213)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendStringByFuture(WsRemoteEndpointImplBase.java:201)
at org.apache.tomcat.websocket.WsRemoteEndpointAsync.sendText(WsRemoteEndpointAsync.java:53)
at cn.pxzs.train.websocket.common.SessionUtils.broadcast(SessionUtils.java:48)
at cn.pxzs.train.websocket.ShakeWapSocket.onClose(ShakeWapSocket.java:76)
... 18 more
不知道哪里出了问题。有没有懂的前辈?
1. 如果想从服务器端推送消息到客户端的话,个人觉得GoEasy推送还不错,它有RestfulAPI支持多语言,而且针对java他们还特别做了SDK,使用很简单方便。同时它也支持客户端推送。由于它支持websocket和polling两种连接方式所以兼顾大多数主流浏览器,低版本的IE浏览器也是支持的,很适合需要快速建立实时web通信的项目。 https://goeasy.io相关博客: http://www.cnblogs.com/jishaochengduo/articles/5552645.html
websocket发送消息的时候会通过一个状态机管理状态,状态为OPEN的时候才允许调用发送方法,调用发送方法后状态修改为TEXT_FULL_WRITING,此时其他线程再调用发送方法就会报状态错误,当正在写的线程写完的时候状态会重新改为OPEN,这时候才能再次调用发送方法,解决办法可以给发送方法加锁,防止并发
总之这个问题是多个线程并发操作一个session做写操作导致的,可以按这个思路排查一下,有必要可以debugWsRemoteEndpointImplBase对应的写方法,看看实际状态机的变化和stacktrace信息但是每个客户端都是不一样的啊,不是在一个客户端发起多个连接,每个都有唯一的客户端ID版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。