handler類處理出入站消息
其餘代碼可以在https://www.ibm.com/developerworks/cn/java/spring5-webflux-reactive/ 找到,
或者 https://gitee.com/zengq-s/webflux-websocket-demo.git
由於網上 都是 客戶端和服務器單個鏈接, 1v1 的例子也沒找到,根據網上部分資料寫出一點 多播的示例。 1v1 這裏不在舉例子
這裏的clients 存儲方式可以根據自己的情況來定。
這裏示例用的是全局變量。 分佈式 環境下clients 暫時沒有解決
@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));
}
}
-
訪問 https://www.websocket.org/echo.html 或者網上找一個websocket頁面 websocket鏈接地址: ws://localhost:8080/echo
-
發送消息效果,沒有過濾sessionId可根據實際修改。
-
通過rest或者消息中間件向websocket發送 hello 消息 http://localhost:8080/sendMessage?message=hello