我必须在Websockets上实现自定义API,这需要:
所以我有以下问题:
将路径参数传递给消息处理程序的正确方法是什么?我可以在处理程序注册中使用ant模式
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(customHandler(), "/api/custom/{clientId}");
}
但是TextWebSocketHandler似乎没有。我现在通过以下方式扩展默认的HttpSessionHandshakeInterceptor来解决这个问题:
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);
}
}
然后在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);
}
}
但在我看来,这种方法有点笨拙。有没有更合适的方法来解决这个问题?
感谢。
答案 0 :(得分:1)
我能给出的最佳建议是遵循内置的子协议支持示例 - 从SubProtocolWebSocketHandler
开始,并SubProtocolHandler
代表它包括StompSubProtocolHandler
实施。 SubProtocolWebSocketHandler
进一步连接到&#34; clientInbound&#34;和&#34; clientOutbound&#34;然后用于形成处理流程以及提供线程边界的通道。
STOMP http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-stomp-message-flow的处理流程有一个描述,其中包括将消息委托给带注释的控制器和/或消息代理,消息代理也可以向下游发送消息给客户。
基本上StompSubProtocolHandler
转换为来自WebSocketMessage
和来自具有协议特定内容的Spring Message
。因此,来自客户端入站通道的控制器,消息代理或任何其他消息使用者与WebSocket传输层分离并且不知道。围绕构建,发送和处理这种子协议消息而构建的许多设施旨在可能用于支持其他类似STOMP的协议。这包括org.springframework.messaging.simp
包中的所有类。
对于URL路径参数,Spring在WebSocket级别提供的任何东西都不是传输层。大多数有趣的东西都发生在子协议级别。例如,对于STOMP,基于目标头和MessageMapping
支持@DestinationVariable
,这与在Spring MVC中使用@PathVariable
相当,但基于目标头,而不是URL。 / p>