WebSocket入門教程(五)-- WebSocket實例:簡單多人聊天室

from:https://blog.csdn.net/u010136741/article/details/51612594javascript

【總目錄】

 
 

【實例簡介】

 
    本文,咱們經過nodejs和javascript實現一個網頁聊天室的demo。主要包括,聊天,改用戶名,查看其餘用戶在線狀態的功能。大體流程爲,用戶訪問網頁,即進入聊天狀態,成爲新遊客,經過底部的輸入框,能夠輸入本身想說的話,點擊發布,信息呈現給全部在聊天的人的頁面。用戶能夠實時修改本身的暱稱,用戶離線上線都會實時廣播給其餘用戶!
 

【效果圖】

 
 
 

【客戶端】

 
    web頁面主要呈如今線人數,聊天信息,一個輸入框和發送按鈕,上代碼:
 
[html]  view plain  copy
 
  1. <!DOCTYPE html>  
  2. <html lang="cn">  
  3. <head>  
  4.     <title>WebSocket chart application</title>  
  5.     <meta charset="utf-8">  
  6.     <meta name="viewport" content="width=device-width, initial-scale=1">  
  7.     <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/css/bootstrap.css">  
  8.     <link rel="stylesheet" href="http://cdn.bootcss.com/tether/1.3.2/css/tether.css"/>  
  9.     <script src="http://cdn.bootcss.com/jquery/2.2.4/jquery.js" ></script>  
  10.     <script src="http://cdn.bootcss.com/tether/1.3.2/js/tether.js"></script>  
  11.     <script src="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/js/bootstrap.js"></script>  
  12.     <script>  
  13.         var ws= new WebSocket('ws://www.liumumu.top:8180');  
  14.         var nickname;  
  15.         ws.onopen = function(e){  
  16.             console.log('Connection to server opened');  
  17.         }  
  18.         function appendLog(type,nickname, message,clientcount) {  
  19.                 var messages = document.getElementById('messages');  
  20.                 var messageElem = document.createElement("li");  
  21.                 var preface_label;  
  22.             if(type==='notification') {  
  23.                         preface_label = "<span class=\"label label-info\">*</span>";  
  24.                     } else if(type==='nick_update') {  
  25.                         preface_label = "<span class=\"label label-warning\">*</span>";  
  26.                     } else {  
  27.                         preface_label = "<span class=\"label label-success\">" + nickname + "</span>";  
  28.                     }  
  29.                 var message_text = "<h2>" + preface_label + "  " + message + "</h2>";  
  30.                 messageElem.innerHTML = message_text;  
  31.                 messages.appendChild(messageElem);  
  32.             var count_people = document.getElementById("count_people");  
  33.                         count_people.innerHTML = clientcount;  
  34.   
  35.             }  
  36.         ws.onmessage = function(e){  
  37.             var data = JSON.parse(e.data);  
  38.             nickname = data.nickname;  
  39.                 appendLog(data.type,data.nickname, data.message,data.clientcount);  
  40.                 console.log("ID: [%s] = %s", data.id, data.message);  
  41.   
  42.   
  43.         }  
  44.         function sendMessage(){  
  45.             var message = $('#message').val().trim();  
  46.             if(message.length<1){  
  47.                 alert("不能發送空內容!");  
  48.                 return;  
  49.             }  
  50.             ws.send($('#message').val());  
  51.             $('#message').val("");  
  52.             $('#message').focus();  
  53.             console.log(ws.bufferedAmount);  
  54.         }  
  55.     </script>  
  56. </head>  
  57. <body lang="cn">  
  58.     <div class="vertical-center">  
  59.     <div class="container">  
  60.         <h2>多人在線聊天DEMO</h2>  
  61.     <hr />  
  62.     <p>當前在線人數:<span id="count_people">0</span></p>  
  63.     <ul id="messages" class="list-unstyled">  
  64.   
  65.         </ul>  
  66.         <hr />  
  67.     <form role="form" id="chat_form" onsubmit="sendMessage(); return false;">  
  68.             <div class="form-group">  
  69.                 <input class="form-control" type="text" name="message" id="message"  
  70.                     placeholder="輸入聊天內容" value="" autofocus/>  
  71.             </div>  
  72.             <button type="button" id="send" class="btn btn-primary"  
  73.           onclick="sendMessage();">發送!</button>  
  74.     </form>  
  75.     </div>  
  76.     </div>  
  77. </body>  
  78. </html>  
    
    javascript 部分,鏈接websocket成功以後,主要是監聽數據返回,和發送數據。
    當用戶編輯好內容,點擊發送按鈕是調用sendMessage方法,發送數據,若是須要修改暱稱,則發送數據格式爲"/nick 暱稱"。
   當服務器返回數據到客戶端,咱們經過appendLog方法對數據作處理,根據type字段,判斷是顯示用戶離線在線信息,仍是顯示聊天信息。最後更新在線人數。
 

【服務器端】

 
    服務器端主要是接收信息,判斷是聊天信息仍是重命名信息,而後發送廣播。同時,當用戶鏈接上服務器端或者關閉鏈接時,服務器也會發送廣播通知其餘用戶。
[javascript]  view plain  copy
 
  1. var WebSocket = require('ws');  
  2. var WebSocketServer = WebSocket.Server,  
  3.     wss = new WebSocketServer({port: 8180});  
  4. var uuid = require('node-uuid');  
  5.   
  6. var clients = [];  
  7.   
  8. function wsSend(type, client_uuid, nickname, message,clientcount) {  
  9.   for(var i=0; i<clients.length; i++) {  
  10.     var clientSocket = clients[i].ws;  
  11.     if(clientSocket.readyState === WebSocket.OPEN) {  
  12.       clientSocket.send(JSON.stringify({  
  13.         "type": type,  
  14.         "id": client_uuid,  
  15.         "nickname": nickname,  
  16.         "message": message,  
  17.         "clientcount":clientcount,  
  18.       }));  
  19.     }  
  20.   }  
  21. }  
  22.   
  23. var clientIndex = 1;  
  24.   
  25. wss.on('connection', function(ws) {  
  26.   var client_uuid = uuid.v4();  
  27.   var nickname = "遊客"+clientIndex;  
  28.   clientIndex+=1;  
  29.   clients.push({"id": client_uuid, "ws": ws, "nickname": nickname});  
  30.   console.log('client [%s] connected', client_uuid);  
  31.   
  32.   var connect_message = nickname + " 來了";  
  33.   wsSend("notification", client_uuid, nickname, connect_message,clients.length);  
  34.   
  35.   ws.on('message', function(message) {  
  36.     if(message.indexOf('/nick') === 0) {  
  37.       var nickname_array = message.split(' ');  
  38.       if(nickname_array.length >= 2) {  
  39.         var old_nickname = nickname;  
  40.         nickname = nickname_array[1];  
  41.         var nickname_message = "用戶 " + old_nickname + " 更名爲: " + nickname;  
  42.         wsSend("nick_update", client_uuid, nickname, nickname_message,clients.length);  
  43.       }  
  44.     } else {  
  45.       wsSend("message", client_uuid, nickname, message,clients.length);  
  46.     }  
  47.   });  
  48.   
  49.   var closeSocket = function(customMessage) {  
  50.     for(var i=0; i<clients.length; i++) {  
  51.         if(clients[i].id == client_uuid) {  
  52.             var disconnect_message;  
  53.             if(customMessage) {  
  54.                 disconnect_message = customMessage;  
  55.             } else {  
  56.                 disconnect_message = nickname + " 走了";  
  57.             }  
  58.   
  59.           clients.splice(i, 1);  
  60.           wsSend("notification", client_uuid, nickname, disconnect_message,clients.length);  
  61.         }  
  62.     }  
  63.   }  
  64.   ws.on('close', function() {  
  65.       closeSocket();  
  66.   });  
  67.   
  68.   process.on('SIGINT', function() {  
  69.       console.log("Closing things");  
  70.       closeSocket('Server has disconnected');  
  71.       process.exit();  
  72.   });  
  73. });  
    咱們定義了wsSend函數用來處理消息的廣播。對每一個鏈接的用戶,咱們默認給他分配爲遊客。爲了實現廣播,咱們用clients數組來保存鏈接的用戶。
相關文章
相關標籤/搜索