【问题标题】:How to implement a custom WebSocket subprotocol with Spring如何使用 Spring 实现自定义 WebSocket 子协议
【发布时间】:2018-07-25 23:25:52
【问题描述】:

我必须在 Spring Boot 应用程序中添加对自定义 WebSocket 子协议(所以不是 STOMP)的支持,但我很难理解我需要提供什么以及 Spring 已经拥有什么。

这是我走了多远:

@Configuration
@EnableWebSocket
public class WebSocketAutoConfiguration implements WebSocketConfigurer {

    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
        webSocketHandlerRegistry.addHandler(this.webSocketHandler(), new String[]{endpointUrl});
    }

    @Bean
    public WebSocketHandler webSocketHandler() {
        ExecutorSubscribableChannel clientInboundChannel = new ExecutorSubscribableChannel();
        ExecutorSubscribableChannel clientOutboundChannel = new ExecutorSubscribableChannel();
        SubProtocolWebSocketHandler subProtocolWebSocketHandler = new SubProtocolWebSocketHandler(clientInboundChannel, clientOutboundChannel);
        subProtocolWebSocketHandler.addProtocolHandler(new SubProtocolHandler() {
            public List<String> getSupportedProtocols() {
                return Collections.singletonList("custom-protocol");
            }

            public void handleMessageFromClient(WebSocketSession session, WebSocketMessage<?> message, MessageChannel outputChannel) throws Exception {
                session.sendMessage(new TextMessage("some message"));
            }

            public void handleMessageToClient(WebSocketSession session, Message<?> message) throws Exception {
            }

            public String resolveSessionId(Message<?> message) {
                return UUID.randomUUID().toString();
            }

            public void afterSessionStarted(WebSocketSession session, MessageChannel outputChannel) throws Exception {
                System.out.println("SESSION STARTED");
            }

            public void afterSessionEnded(WebSocketSession session, CloseStatus closeStatus, MessageChannel outputChannel) throws Exception {
                session.close();
                System.out.println("SESSION ENDED");
            }
        });
        return subProtocolWebSocketHandler;
    }
}

这有效,因为handleMessageFromClient 确实在网络套接字消息上被触发,但我无法理解MessageChannel outputChannelhandleMessageToClient 的用途。

是否可以使用SubProtocolWebSocketHandler 获得PerConnectionWebSocketHandler 语义?

这方面的文档基本上不存在,例如handleMessageToClient 的文档说:

将给定的 {@link Message} 处理给与给定 WebSocket 会话关联的客户端。

嗯,太棒了。而且 STOMP 的实现令人难以置信,因此它们不是很适合作为指导。

任何示例,宽泛的步骤或任何东西,真的,将不胜感激。

【问题讨论】:

    标签: java spring websocket spring-websocket


    【解决方案1】:

    事实证明这非常容易。根本不需要惹SubProtocolWebSocketHandler。唯一的要求是提供的WebSocketHandler 实现SubProtocolCapable

    public class CustomHandler implements WebSocketHandler, SubProtocolCapable {
       ...
    }
    

    就是这样。要创建一个PerConnectionWebSocketHandler,只需扩展它并实现SubProtocolCapable就足够了:

    public class CustomHandler extends PerConnectionWebSocketHandler implements SubProtocolCapable {
       ...
    }
    

    【讨论】:

    • 我只是好奇,你为什么要实现自己的子协议?
    • @lqbweb 我正在实现graphql-ws 子协议,以便与 Apollo 客户端兼容。
    猜你喜欢
    • 2017-05-31
    • 2014-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    • 1970-01-01
    • 2015-05-25
    相关资源
    最近更新 更多