使用WebSocket的時候,由於要推送消息,可能有多個客戶端同時在線,通常的處理方法都是把這些Channel放進一個Room裏,而後一塊兒通知。 上一篇已經簡單的說明基於Nutz的Undertow插件集成WebSocket的方法,這裏跟進一步,看看如何模擬Room。web
//添加WebSocket的Handler PathHandler pathHandler = Handlers.path().addPrefixPath("/myWebsocket", websocket(new WebSocketConnectionCallback() { @Override public void onConnect(WebSocketHttpExchange exchange, WebSocketChannel channel) { channel.getReceiveSetter().set(new AbstractReceiveListener() { @Override protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) { //獲取頁面傳遞的message裏的數據,這裏封裝了Nutz的一個Map工具,NutMap,裏面包含了動做和房間名 //獲取鏈接的channel //channel有一個setAttrbute方法,能夠放一個UUID進去,以保證惟一。我本身是用「房間名@UUID」,用處後面會講 //使用一個全局的Map,存進這個channel,並放進獲取的房間名爲Key的Map中 //這樣就能在發送的時候,遍歷某個房間裏的全部channel,而後sendText了 } @Override protected void onClose(WebSocketChannel channel){ //在關閉的時候,記得找到房間,並移除這個channel //這個時候就須要這個channel裏的attribute裏的id了,解析出房間名,就能夠在這個房間名爲Key的Map裏移除channel了 //有時候,一些特殊的需求,須要按照Channel來通訊,就是說一個用戶一個Channel。這裏沒法直接獲取Session,咱們能夠使用一種變通的方法: //用戶登陸成功以後,在Session裏保存一個UUID,而後頁面初始化的時候,用這個UUID做爲房間名,就是惟一的了。 //到時候,只要能找到Session裏的這個UUID,就能夠單獨給這個房間發送消息了 } }); channel.resumeReceives(); } })).addPrefixPath(contextPath, servletHandler);
暫時用文字說明一下,有空了補充代碼。websocket