【问题标题】:keeping connection alive to websocket when using ServerWebSocketContainer使用 ServerWebSocketContainer 时保持与 websocket 的连接
【发布时间】:2015-10-13 12:45:46
【问题描述】:

我试图创建一个基于 websocket 的应用程序,其中服务器需要使用心跳与客户端保持连接。 我检查了服务器ServerWebSocketContainer.SockJsServiceOptions 类是否相同,但无法使用它。我正在使用 spring-integration 示例中的代码

@Bean
ServerWebSocketContainer serverWebSocketContainer() {
    return new ServerWebSocketContainer("/messages").withSockJs();
}

@Bean
MessageHandler webSocketOutboundAdapter() {
    return new WebSocketOutboundMessageHandler(serverWebSocketContainer());
}

@Bean(name = "webSocketFlow.input")
MessageChannel requestChannel() {
    return new DirectChannel();
}

@Bean
IntegrationFlow webSocketFlow() {
    return f -> {
        Function<Message , Object> splitter = m -> serverWebSocketContainer()
                .getSessions()
                .keySet()
                .stream()
                .map(s -> MessageBuilder.fromMessage(m)
                        .setHeader(SimpMessageHeaderAccessor.SESSION_ID_HEADER, s)
                        .build())
                .collect(Collectors.toList());
        f.split( Message.class, splitter)
                .channel(c -> c.executor(Executors.newCachedThreadPool()))
                .handle(webSocketOutboundAdapter());
    };
}

@RequestMapping("/hi/{name}")
public void send(@PathVariable String name) {
    requestChannel().send(MessageBuilder.withPayload(name).build());
}

请告诉我如何设置心跳选项以确保连接保持活动状态,除非客户端自行注销。

谢谢

【问题讨论】:

    标签: spring-boot spring-integration spring-websocket


    【解决方案1】:

    实际上你做对了,但错过了一点便利:-)。 你可以这样配置:

    @Bean
    ServerWebSocketContainer serverWebSocketContainer() {
        return new ServerWebSocketContainer("/messages")
              .withSockJs(new ServerWebSocketContainer.SockJsServiceOptions()
                                      .setHeartbeatTime(60_000));
    }
    

    虽然我不清楚为什么你需要配置它:

    /**
     * The amount of time in milliseconds when the server has not sent any
     * messages and after which the server should send a heartbeat frame to the
     * client in order to keep the connection from breaking.
     * <p>The default value is 25,000 (25 seconds).
     */
    public SockJsServiceRegistration setHeartbeatTime(long heartbeatTime) {
        this.heartbeatTime = heartbeatTime;
        return this;
    }
    

    更新

    在 Spring 集成示例中,我们有类似 stomp-chat 的应用程序。

    我对@9​​87654326@ 做了类似的事情:

    <int-websocket:server-container id="serverWebSocketContainer" path="/chat">
        <int-websocket:sockjs heartbeat-time="10000"/>
    </int-websocket:server-container>
    

    将此添加到application.properties

    logging.level.org.springframework.web.socket.sockjs.transport.session=trace
    

    这个给index.html

    sock.onheartbeat = function() {
        console.log('heartbeat');
    };
    

    连接客户端后,我在服务器日志中看到:

    2015-10-13 19:03:06.574 TRACE 7960 --- [       SockJS-3] s.w.s.s.t.s.WebSocketServerSockJsSession : Writing SockJsFrame content='h'
    2015-10-13 19:03:06.574 TRACE 7960 --- [       SockJS-3] s.w.s.s.t.s.WebSocketServerSockJsSession : Cancelling heartbeat in session sogfe2dn
    2015-10-13 19:03:06.574 TRACE 7960 --- [       SockJS-3] s.w.s.s.t.s.WebSocketServerSockJsSession : Scheduled heartbeat in session sogfe2dn
    2015-10-13 19:03:16.576 TRACE 7960 --- [       SockJS-8] s.w.s.s.t.s.WebSocketServerSockJsSession : Preparing to write SockJsFrame content='h'
    2015-10-13 19:03:16.576 TRACE 7960 --- [       SockJS-8] s.w.s.s.t.s.WebSocketServerSockJsSession : Writing SockJsFrame content='h'
    2015-10-13 19:03:16.576 TRACE 7960 --- [       SockJS-8] s.w.s.s.t.s.WebSocketServerSockJsSession : Cancelling heartbeat in session sogfe2dn
    2015-10-13 19:03:16.576 TRACE 7960 --- [       SockJS-8] s.w.s.s.t.s.WebSocketServerSockJsSession : Scheduled heartbeat in session sogfe2dn
    

    在浏览器的控制台中我看到了这个:

    所以,看起来heart-beat 功能运行良好...

    【讨论】:

    • 5-6 分钟后,连接变得陈旧和超时。所以,我需要一种方法来保持连接。
    • 好吧。也许那是您的 HTTP 会话的 TTL?.. 死 HTTP 会话会导致其所有 WebSocket 会话关闭。让我知道你对此事的立场。
    • 太棒了!你介意分享那个修复吗?作为对您的问题和评论的编辑,在这里通知我就足够了。
    • 服务器正在发送心跳,但客户端没有处理它。因此,当心跳丢失时,连接将关闭。
    • 请分享您在客户端修复的内容。也许我们在代码中遗漏了任何东西......
    猜你喜欢
    • 2019-07-19
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-29
    • 2010-10-21
    • 2017-05-03
    相关资源
    最近更新 更多