Spring Boot中Stomp Session Handler连接后afterConnected()未触发问题
问题分析与解决
核心问题:协议不匹配
Finnhub提供的WebSocket是原生WebSocket协议,而你使用的WebSocketStompClient是专门用于连接STOMP协议的WebSocket服务端的。两者协议不兼容,导致STOMP握手流程无法完成,因此afterConnected()永远不会被触发,最终超时出现传输异常。
解决方案:改用原生WebSocket客户端
放弃StompSessionHandler相关组件,直接使用StandardWebSocketClient结合WebSocketHandler实现原生WebSocket连接:
修改后的代码示例
import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.WebSocketMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.client.standard.StandardWebSocketClient; import org.springframework.web.socket.handler.TextWebSocketHandler; @Service public class MyWebSocketClient { @EventListener(value = ApplicationReadyEvent.class) public void connect() { System.out.println("In connection..."); StandardWebSocketClient client = new StandardWebSocketClient(); WebSocketHandler handler = new TextWebSocketHandler() { @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { System.out.println("After Connected Called"); // 连接建立后可发送Finnhub要求的订阅指令,示例为订阅AAPL行情 session.sendMessage(new TextMessage("{\"type\":\"subscribe\",\"symbol\":\"AAPL\"}")); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 处理服务端推送的消息 System.out.println("Received message: " + message.getPayload()); } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { System.out.println("failed in transport: " + exception.getMessage()); } }; try { client.doHandshake(handler, "wss://ws.finnhub.io/?token=my_token").get(); System.out.println("connected"); } catch (Exception e) { System.out.println("Failed: " + e.getMessage()); e.printStackTrace(); } } }
额外说明
- Finnhub的WebSocket仅支持原生协议,需发送JSON格式的订阅/取消订阅指令,不兼容STOMP的帧格式。
- 原代码中
connectAsync().get()会阻塞线程等待STOMP握手完成,但由于服务端不支持STOMP,会一直等待至超时,这就是控制台延迟出现传输异常的原因。
内容的提问来源于stack exchange,提问作者GDA 973
相关产品推荐
相关产品推荐

