Webflux和WebSocket,发送到特定的会话ID

时间:2018-07-31 08:32:39

标签: java-8 spring-webflux project-reactor reactive-streams

传递到套接字的每个会话数据都会广播给所有用户,因为每个会话都订阅UnicastProcessor eventPublisher。

如何通过事件数据将数据发送到单个会话ID,而不是全部发送给会话ID?

@Override
public Mono<Void> handle(WebSocketSession session) {
    WebSocketMessageSubscriber subscriber = new WebSocketMessageSubscriber(eventPublisher);
    session.receive()
            .map(WebSocketMessage::getPayloadAsText)
            .map(this::toEvent)
            .subscribe(subscriber::onNext, subscriber::onError, subscriber::onComplete);
    return session.send(outputEvents.map(session::textMessage));
}

我的用例要求我同时包括以下两个选项:将任何客户端的任何已更改状态广播到所有已连接的套接字,以及将响应发送到特定客户端(sessionId)的能力,该特定客户端在其中发送请求特定事件

Github link

还是应该从同一websocket路径将其路由到2个不同的处理程序? 请注意,来自javascript

new WebSocket(url/path)  creates a socket connection

如果不创建或实例化不需要的新WebSocket对象,则无法更改路径。 我对为每个浏览器客户端创建2个套接字不感兴趣... 所以我的目标是通过1个单个websocket路径建立服务器连接

@Bean
public HandlerMapping webSocketMapping(UnicastProcessor<Event> eventPublisher, Flux<Event> events) {
    Map<String, Object> map = new HashMap<>();
    map.put("/websocket/chat", new ChatSocketHandler(eventPublisher, events));
    SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping();
    simpleUrlHandlerMapping.setUrlMap(map);

    //Without the order things break :-/
    simpleUrlHandlerMapping.setOrder(10);
    return simpleUrlHandlerMapping;
}

如果愿意的话,很高兴看到这种解决方案的示例

1 个答案:

答案 0 :(得分:0)

使用基于servlet的Web套接字,这是可能的,因为您可以将Websocket连接到消息传递代理。然后,消息传递代理将负责将消息发送到特定客户端。 但是,随着提供了该春季的基于webflux的websocket,我无法设法使消息传递代理发挥作用。似乎在春季webflux中尚无支持。

在此处找到带有servlet堆栈的示例: https://github.com/bmd007/RealtimeNoteSharing.git