使用ServerWebSocketContainer时保持连接活动到websocket

时间:2015-10-13 12:45:46

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

我正在尝试创建一个基于websocket的应用程序,其中服务器需要使用heartbeat保持与客户端的连接。 我检查了服务器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());
}

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

由于

1 个答案:

答案 0 :(得分: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 Integration Samples中,我们有类似stomp-chat application。

的内容

我在stomp-server.xml

做了类似的事情
<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

在浏览器的控制台中,我看到:

enter image description here

因此,看起来heart-beat功能效果很好......