在 Java 中连接到 websocket

Posted

技术标签:

【中文标题】在 Java 中连接到 websocket【英文标题】:Connecting to a websocket in Java 【发布时间】:2018-02-06 10:39:37 【问题描述】:

我正在尝试连接到网络套接字wss://ws-feed.gdax.com

我已经在 J​​avaScript (See here) 中完成了这项工作,但我正在尝试将连接服务器端移动到我的 Spring Boot 应用程序中。

到目前为止我有:

@SpringBootApplication
public class DemoApplication implements CommandLineRunner 

    private Logger LOG = LoggerFactory.getLogger(DemoApplication.class);

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

    @Override
    public void run(String... args) throws Exception 
        WebSocketContainer container = ContainerProvider.getWebSocketContainer();
        container.setDefaultMaxTextMessageBufferSize(64*1024);
        WebSocketClient simpleWebSocketClient = new StandardWebSocketClient(container);
        List<Transport> transports = new ArrayList<>(1);
        transports.add(new WebSocketTransport(simpleWebSocketClient));
        SockJsClient sockJsClient = new SockJsClient(transports);
        WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient);
        stompClient.setMessageConverter(new MappingJackson2MessageConverter());

        LOG.info("Connecting To [wss://ws-feed.gdax.com]");
        StompSession session = stompClient.connect("wss://ws-feed.gdax.com", new GDAXHandler()).get();
    

    private class GDAXHandler extends WebSocketHttpHeaders implements StompSessionHandler 

        @Override
        public void afterConnected(StompSession session, StompHeaders connectedHeaders) 
            LOG.info("Connected");
            String payload = "\"type\": \"subscribe\",\"channels\":[\"name\": \"ticker\",\"product_ids\": [\"ETH-EUR\"]]\"";
            LOG.info("Sending [" + payload + "]");
            session.send("/", payload);
        

        @Override
        public void handleException(StompSession session, StompCommand command, StompHeaders headers, byte[] payload, Throwable exception) 
            LOG.error("Exception", exception);
        

        @Override
        public void handleTransportError(StompSession session, Throwable exception) 
            LOG.error("Transport Error", exception);
        

        @Override
        public Type getPayloadType(StompHeaders headers) 
            return String.class;
        

        @Override
        public void handleFrame(StompHeaders headers, Object payload) 
            LOG.info("Frame [" + payload + "]");
        
    

如果我运行这个应用程序,输出是:

INFO Tomcat 在端口启动:8080 (http)

INFO 连接到 [wss://ws-feed.gdax.com]

INFO 启动 ApplicationContext 时出错。要显示自动配置报告,请在启用“调试”的情况下重新运行您的应用程序。

错误传输错误 org.springframework.messaging.simp.stomp.ConnectionLostException:连接关闭

原因: org.springframework.messaging.simp.stomp.ConnectionLostException: 连接关闭于 org.springframework.messaging.simp.stomp.DefaultStompSession.afterConnectionClosed(DefaultStompSession.java:487) ~[spring-messaging-4.3.13.RELEASE.jar:4.3.13.RELEASE] 在 org.springframework.web.socket.messaging.WebSocketStompClient$WebSocketTcpConnectionHandlerAdapter.afterConnectionClosed(WebSocketStompClient.java:354) ~[spring-websocket-4.3.13.RELEASE.jar:4.3.13.RELEASE] 在 org.springframework.web.socket.sockjs.client.AbstractClientSockJsSession.afterTransportClosed(AbstractClientSockJsSession.java:324) ~[spring-websocket-4.3.13.RELEASE.jar:4.3.13.RELEASE] 在 org.springframework.web.socket.sockjs.client.WebSocketTransport$ClientSockJsWebSocketHandler.afterConnectionClosed(WebSocketTransport.java:172) ~[spring-websocket-4.3.13.RELEASE.jar:4.3.13.RELEASE] ...

它甚至从未达到Connected 状态。我做错了什么?

【问题讨论】:

尝试直接使用WebSocketClient,不要换行到WebSocketStompClient。根据您的 javascript 示例,只有普通的 WebSocket 交互,没有任何 STOMP 子协议。 @ArtemBilan 太棒了!我完全误解了 STOMP 是什么。 【参考方案1】:

解决方案(感谢@ArtemBilan)是摆脱 STOMP 并使用基本的 Web Socket,例如

@SpringBootApplication
public class DemoApplication implements CommandLineRunner 

    private Logger LOG = LoggerFactory.getLogger(DemoApplication.class);

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

    @Override
    public void run(String... args) 
        LOG.info("Connecting To [wss://ws-feed.gdax.com]");
        WebSocketConnectionManager connectionManager = new WebSocketConnectionManager(new StandardWebSocketClient(), new GDAXWebSocketHandler(), "wss://ws-feed.gdax.com");
        connectionManager.start();
    

    private class GDAXWebSocketHandler extends TextWebSocketHandler 

        @Override
        public void handleTextMessage(WebSocketSession session, TextMessage message) 
            LOG.info("Message Received [" + message.getPayload() + "]");
        

        @Override
        public void afterConnectionEstablished(WebSocketSession session) throws Exception 
            LOG.info("Connected");
            String payload = "\"type\": \"subscribe\",\"channels\":[\"name\": \"ticker\",\"product_ids\": [\"ETH-EUR\"]]";
            LOG.info("Sending [" + payload + "]");
            session.sendMessage(new TextMessage(payload));
        

        @Override
        public void handleTransportError(WebSocketSession session, Throwable exception) 
            LOG.error("Transport Error", exception);
        

        @Override
        public void afterConnectionClosed(WebSocketSession session, CloseStatus status)
            LOG.info("Connection Closed [" + status.getReason() + "]");
        
    

输出日志:

INFO Tomcat started on port(s): 8080 (http)

INFO Connecting To [wss://ws-feed.gdax.com]

INFO Starting WebSocketConnectionManager

INFO Connecting to WebSocket at wss://ws-feed.gdax.com

INFO Started DemoApplication in 2.324 seconds (JVM running for 3.076)

INFO Connected

INFO Sending ["type": "subscribe","channels":["name": "ticker","product_ids": ["ETH-EUR"]]]

INFO Successfully connected

INFO Message Received ["type":"ticker","sequence":569701928,"product_id":"ETH-EUR","price":"641.65000000","open_24h":"465.26000000","volume_24h":"100991.88666517","low_24h":"641.65000000","high_24h":"657.17000000","volume_30d":"1129037.16627038","best_bid":"641.59","best_ask":"641.65"]

INFO Message Received ["type":"subscriptions","channels":["name":"ticker","product_ids":["ETH-EUR"]]]

INFO Message Received ["type":"ticker","sequence":569702018,"product_id":"ETH-EUR","price":"641.65000000","open_24h":"465.26000000","volume_24h":"100969.00195695","low_24h":"641.65000000","high_24h":"657.17000000","volume_30d":"1129014.28156216","best_bid":"641.64","best_ask":"641.73","side":"buy","time":"2018-02-07T09:07:49.556000Z","trade_id":2980644,"last_size":"1.00879065"]

【讨论】:

这对我有用,但相同的代码不适用于沙箱。参考:***.com/questions/49648694/…

以上是关于在 Java 中连接到 websocket的主要内容,如果未能解决你的问题,请参考以下文章

如何在java中连接到gtalk?

如何以 SYS 身份在 Java 中连接到 Oracle?

在java中连接到sql数据库[关闭]

如何在java中连接到sybase的优势数据库

在 Java (Android) 中连接到 IOCP 服务器

如何在 PySpark 中连接到 Presto JDBC?