我需要实现一个自定义的API,使用Websockets进行通信,需要满足以下要求:
- 使用类似WAMP的自定义子协议
- 在socket URI中包含路径参数
因此,我有以下问题:
- Is there any documentation or guides on implementing custom subprotocols in Spring? Protocol requires that exact version must be specified in the Sec-Websocket-Protocol field. Where this field could be read on server side?
What is a proper way to pass path parameters into a message handler? I could use ant patterns in handler registration
@Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(customHandler(), "/api/custom/{clientId}"); }
but those seems not available at TextWebSocketHandler. I'm solved this for now by extending default HttpSessionHandshakeInterceptor in a following way:
public class CustomHandshakeInterceptor extends HttpSessionHandshakeInterceptor { private static final UriTemplate URI_TEMPLATE = new UriTemplate("/api/custom/{clientId}"); @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { Map<String, String> segments = URI_TEMPLATE.match(request.getURI().getPath()); attributes.put("CLIENTID", segments.get("clientId")); return super.beforeHandshake(request, response, wsHandler, attributes); } }
and then accessing it in TextWebSocketHandler:
public class CustomHandler extends TextWebSocketHandler { @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { super.handleTextMessage(session, message); String clientId = session.getAttributes().get("CLIENTID"); ... session.sendMessage(response); } }
but this method, in my opinion, is a bit clunky. Is there more proper way to solve this?