Springboot Webflux Websocket 多人聊天

springboot webflux websocket 實現多人聊天。

handler類處理出入站消息

其餘代碼可以在https://www.ibm.com/developerworks/cn/java/spring5-webflux-reactive/ 找到,

或者 https://gitee.com/zengq-s/webflux-websocket-demo.git 

由於網上 都是 客戶端和服務器單個鏈接, 1v1 的例子也沒找到,根據網上部分資料寫出一點 多播的示例。 1v1不在舉例子

clients 存儲方式可以根據自己的情況來定。

由於websocket只能存放在各自服務器,在分佈式環境下需要通過消息中間件來觸發消息。

這裏clients直接保存在了handler,可根據實際情況更改, 分佈式 環境下可以使用 redis的stream 或者rabbitmq等消息中間件實現消息發送。這裏選擇 redis 的stream。

文章中沒有更新redis stream代碼。 要查看stream相關可以檢出demo查看。


@Slf4j
@Component
public class EchoHandler  implements WebSocketHandler {


    // 緩存session
    static Map<String, SocketClient> clients = new ConcurrentHashMap<>();

    @Override
    public Mono<Void> handle(WebSocketSession session) {
        String id = session.getId();
        //  出站
        Mono<Void> output = session.send(Flux.create(sink -> clients.put(id, new SocketClient( sink,session))));
        //入站
        Mono<Void> input = session.receive()
                .map(WebSocketMessage::getPayloadAsText).map(msg ->  msg)
                .doOnNext(msg->sendOthers(msg)).then();
        // 合併
        return  Mono.zip(  input,output).then();
    }

    public static Map<String, SocketClient> getSessions() {
        return clients;
    }

    /**
     *  廣播
     * @author zengq
     * @date 2020/5/18 5:20
     */
    public void sendOthers(String message) {
        Map<String, SocketClient> sessions = getSessions();
        sessions.forEach((sessionId,client) ->
            client.sendData("Server Message: "+message)
        );
    }
}

@Slf4j
@Data
public class SocketClient {
    private FluxSink<WebSocketMessage> sink;
    private WebSocketSession session;

    public SocketClient(FluxSink<WebSocketMessage> sink, WebSocketSession session) {
        this.sink = sink;
        this.session = session;
    }

    public void sendData(String data) {
        sink.next(session.textMessage(data));
    }

}
  1. 訪問 https://www.websocket.org/echo.html 或者網上找一個websocket頁面 websocket鏈接地址: ws://localhost:8080/echo

  2. 發送消息效果,沒有過濾sessionId可根據實際修改。發送消息效果,沒有過濾sessionId可根據實際修改

  3. 通過rest或者消息中間件向websocket發送 hello 消息  http://localhost:8080/sendMessage?message=hello 

  4. 通過rest或者消息中間件向websocket發送消息

分別啓動端口了8080和8081 

可以看到3個客戶端和2個服務器情況下, 消息可以互通 。

stream 類似kafka可能會丟失,可以看情況選擇。這裏是聊天服務,選擇stream沒什麼關係。

 


 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章