程旭清
2021-08-15 16:04
采纳率: 20%
浏览 75
已结题

webSocket部署在tomcat上报错?到底是什么问题

WebSocketConfig配置类
@Configuration
public class WebSocketConfig {

/**
 * 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint
 */
@Bean
public ServerEndpointExporter serverEndpointExporter() {
    return new ServerEndpointExporter();
}


@Autowired
public void setMessageService(UserInfoServiceI userInfoService){
    WebSocketController.userInfoService = userInfoService;
}

}
WebSocket类
@Component
@ServerEndpoint(value = "/websocket/{id}")
public class WebSocketController {

private static final Logger logger = Logger.getLogger(WebSocketController.class);

public static UserInfoServiceI userInfoService;

/**
 * 客户端ID
 */
private String id = "";

/**
 * 与某个客户端的连接会话,需要通过它来给客户端发送数据
 */
private Session session;

/**
 * 记录当前在线连接数(为保证线程安全,须对使用此变量的方法加lock或synchronized)
 */
private static int onlineCount = 0;

/**
 * 用来存储当前在线的客户端(此map线程安全)
 */
private static ConcurrentHashMap<String, WebSocketController> webSocketMap = new ConcurrentHashMap<>();

// /**
// * 用于存储用户
// */
private static ConcurrentHashMap<String, Session> sessionMap = new ConcurrentHashMap<>();

/**
 * 连接建立成功后调用
 */
@OnOpen
public void onOpen(@PathParam(value = "id") String id, Session session) {
    //设置长连接时间1小时
    session.setMaxIdleTimeout(3600000);

这里展示部分代码
部署在tomcat上,没有用nginx代理
下面报错的地方在onError方法里面
@OnError
public void onError(Session session, Throwable error) {
logger.error("onError==WebSocket发生错误id["+session.getId()+"]",error);
}
java.io.EOFException
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1301)
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1234)
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:75)
at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:183)
at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:162)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:156)
at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:60)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:59)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:831)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1629)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
据网上查询到的解释
1,如果一端的Socket被关闭(或主动关闭,或因为异常退出而 引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。
Socket默认连接60秒,60秒之内没有进行心跳交互,即读写数据,就会自动关闭连接。
2,一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。
感觉比较靠谱但是解决办法
解决办法:
1、设置tomcat最大连接数,最大等待数,最大线程数

img

2、服务端开启线程每20秒群发消息

img

3、Tomcat Session过期时间
前两个都是修改tomcat的配置文件conf
在server.xml中定义context时采用如下定义:
xml 代码

img

都试过了还是不行

  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 收藏
  • 邀请回答

相关推荐 更多相似问题