如何使用 Spring 实现自定义 WebSocket 子协议

How to implement a custom WebSocket subprotocol with Spring

我必须在 Spring 引导应用程序中添加对自定义 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 的文档说:

Handle the given {@link Message} to the client associated with the given WebSocket session.

嗯,太棒了。 STOMP 的实现令人难以置信,因此它们作为指南不是很有用。

任何例子、广泛的步骤或任何东西,真的,将不胜感激。

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

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

就是这样。要制作 PerConnectionWebSocketHandler,只需扩展它并实现 SubProtocolCapable:

就足够了
public class CustomHandler extends PerConnectionWebSocketHandler implements SubProtocolCapable {
   ...
}