gpt4 book ai didi

tomcat - 基于 Spring Boot 的 WebSocket 服务器在格式错误的数据包后变得无响应

转载 作者:行者123 更新时间:2023-11-28 22:16:22 31 4
gpt4 key购买 nike

我有一个基于 Spring Boot 1.5.9.RELEASE 的普通 WebSocket 应用程序。

SocketHandler.java:

import org.springframework.stereotype.Component; 
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.List;
import java.io.IOException;

@Component
public class SocketHandler extends TextWebSocketHandler {

List<WebSocketSession> sessions = new CopyOnWriteArrayList<WebSocketSession>();

@Override
public void handleTextMessage(WebSocketSession session, TextMessage message)
throws InterruptedException, IOException {
for(WebSocketSession webSocketSession : sessions) {
webSocketSession.sendMessage(message);
}
}

@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
//the messages will be broadcasted to all users.
sessions.add(session);
}
}

WebSocketConfig.java:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new SocketHandler(), "/name");
}
}

主要.java:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main {

public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}

我使用嵌入式 Tomcat 服务器。

当我从一个简单的 HTML/JavaScript 页面访问应用程序时,它工作得很好。但是当我尝试使用 native WebSocket 实现 ( cwebsocket ) 时,整个服务器在第一次请求后变得无响应。第一个请求成功通过但最后有这个异常:

018-01-18 11:32:44.666 ERROR 12567 --- [nio-8080-exec-3] w.s.h.ExceptionWebSocketHandlerDecorator : Closing session due to exception for StandardWebSocketSession[id=1, uri=/name]

java.lang.IllegalStateException: The WebSocket session [0] has been closed and no method (apart from close()) may be called on a closed session
at org.apache.tomcat.websocket.WsSession.checkState(WsSession.java:806) ~[tomcat-embed-websocket-8.5.23.jar:8.5.23]
at org.apache.tomcat.websocket.WsSession.getBasicRemote(WsSession.java:432) ~[tomcat-embed-websocket-8.5.23.jar:8.5.23]
at org.springframework.web.socket.adapter.standard.StandardWebSocketSession.sendTextMessage(StandardWebSocketSession.java:203) ~[spring-websocket-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.socket.adapter.AbstractWebSocketSession.sendMessage(AbstractWebSocketSession.java:101) ~[spring-websocket-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at com.wattsense.service.prototype.websocket.SocketHandler.handleTextMessage(SocketHandler.java:20) ~[main/:na]
at org.springframework.web.socket.handler.AbstractWebSocketHandler.handleMessage(AbstractWebSocketHandler.java:43) ~[spring-websocket-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.socket.handler.WebSocketHandlerDecorator.handleMessage(WebSocketHandlerDecorator.java:75) ~[spring-websocket-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator.handleMessage(LoggingWebSocketHandlerDecorator.java:56) ~[spring-websocket-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator.handleMessage(ExceptionWebSocketHandlerDecorator.java:58) ~[spring-websocket-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.handleTextMessage(StandardWebSocketHandlerAdapter.java:110) [spring-websocket-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.access$000(StandardWebSocketHandlerAdapter.java:42) [spring-websocket-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:81) [spring-websocket-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:78) [spring-websocket-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:395) [tomcat-embed-websocket-8.5.23.jar:8.5.23]
at org.apache.tomcat.websocket.server.WsFrameServer.sendMessageText(WsFrameServer.java:119) [tomcat-embed-websocket-8.5.23.jar:8.5.23]
at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:495) [tomcat-embed-websocket-8.5.23.jar:8.5.23]
at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:294) [tomcat-embed-websocket-8.5.23.jar:8.5.23]
at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:133) [tomcat-embed-websocket-8.5.23.jar:8.5.23]
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:82) [tomcat-embed-websocket-8.5.23.jar:8.5.23]
at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:171) [tomcat-embed-websocket-8.5.23.jar:8.5.23]
at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:151) [tomcat-embed-websocket-8.5.23.jar:8.5.23]
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:148) [tomcat-embed-websocket-8.5.23.jar:8.5.23]
at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.23.jar:8.5.23]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.23.jar:8.5.23]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]

很明显,cwebsocket 在 session 结束时发送了一个格式错误的数据包。

但是没有任何效果,没有服务于 WebSocket 请求,也没有抛出进一步的异常。嵌入式 Tomcat 的普通 Web 服务器部分可以工作,它为 HTML/JavaScript 应用程序提供服务,但该应用程序也无法打开 WebSocket 连接。

显然,cwebsocket 中存在问题,但这与我无关。我更担心整个服务器因客户端故障而宕机。任何人都有想法,如何解决这个问题?

我已经尝试过 TLS/SSL 配置和 Spring Boot 2.0.0.M7,症状是一样的。

最佳答案

我终于有了一个可行的解决方案。从上面的堆栈跟踪中可以看出,WebSocketSession.sendMessage 方法抛出了一个异常。最初的实现没有处理这个异常,而是让它冒泡。因为作为WebSocketHandler解释:鼓励此接口(interface)的实现在有意义的地方处理本地异常,或者让异常冒泡,在这种情况下,默认情况下记录异常并关闭 session 并返回 SERVER_ERROR(1011)。

冒泡异常时出了点问题,因为它杀死了整个 websocket 服务器。

解决方法:



 尝试{
webSocketSession.sendMessage(消息);
} catch (异常前){
LOGGER.log( Level.SEVERE,"handleTextMessage",ex );
同步( session ){
sessions.remove(webSocketSession);
}
}

关于tomcat - 基于 Spring Boot 的 WebSocket 服务器在格式错误的数据包后变得无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48319866/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com