from:https://blog.csdn.net/u010136741/article/details/51612594javascript
【總目錄】
【實例簡介】
本文,咱們經過nodejs和javascript實現一個網頁聊天室的demo。主要包括,聊天,改用戶名,查看其餘用戶在線狀態的功能。大體流程爲,用戶訪問網頁,即進入聊天狀態,成爲新遊客,經過底部的輸入框,能夠輸入本身想說的話,點擊發布,信息呈現給全部在聊天的人的頁面。用戶能夠實時修改本身的暱稱,用戶離線上線都會實時廣播給其餘用戶!
【效果圖】
【客戶端】
web頁面主要呈如今線人數,聊天信息,一個輸入框和發送按鈕,上代碼:
- <!DOCTYPE html>
- <html lang="cn">
- <head>
- <title>WebSocket chart application</title>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/css/bootstrap.css">
- <link rel="stylesheet" href="http://cdn.bootcss.com/tether/1.3.2/css/tether.css"/>
- <script src="http://cdn.bootcss.com/jquery/2.2.4/jquery.js" ></script>
- <script src="http://cdn.bootcss.com/tether/1.3.2/js/tether.js"></script>
- <script src="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/js/bootstrap.js"></script>
- <script>
- var ws= new WebSocket('ws://www.liumumu.top:8180');
- var nickname;
- ws.onopen = function(e){
- console.log('Connection to server opened');
- }
- function appendLog(type,nickname, message,clientcount) {
- var messages = document.getElementById('messages');
- var messageElem = document.createElement("li");
- var preface_label;
- if(type==='notification') {
- preface_label = "<span class=\"label label-info\">*</span>";
- } else if(type==='nick_update') {
- preface_label = "<span class=\"label label-warning\">*</span>";
- } else {
- preface_label = "<span class=\"label label-success\">" + nickname + "</span>";
- }
- var message_text = "<h2>" + preface_label + " " + message + "</h2>";
- messageElem.innerHTML = message_text;
- messages.appendChild(messageElem);
- var count_people = document.getElementById("count_people");
- count_people.innerHTML = clientcount;
-
- }
- ws.onmessage = function(e){
- var data = JSON.parse(e.data);
- nickname = data.nickname;
- appendLog(data.type,data.nickname, data.message,data.clientcount);
- console.log("ID: [%s] = %s", data.id, data.message);
-
-
- }
- function sendMessage(){
- var message = $('#message').val().trim();
- if(message.length<1){
- alert("不能發送空內容!");
- return;
- }
- ws.send($('#message').val());
- $('#message').val("");
- $('#message').focus();
- console.log(ws.bufferedAmount);
- }
- </script>
- </head>
- <body lang="cn">
- <div class="vertical-center">
- <div class="container">
- <h2>多人在線聊天DEMO</h2>
- <hr />
- <p>當前在線人數:<span id="count_people">0</span></p>
- <ul id="messages" class="list-unstyled">
-
- </ul>
- <hr />
- <form role="form" id="chat_form" onsubmit="sendMessage(); return false;">
- <div class="form-group">
- <input class="form-control" type="text" name="message" id="message"
- placeholder="輸入聊天內容" value="" autofocus/>
- </div>
- <button type="button" id="send" class="btn btn-primary"
- onclick="sendMessage();">發送!</button>
- </form>
- </div>
- </div>
- </body>
- </html>
javascript 部分,鏈接websocket成功以後,主要是監聽數據返回,和發送數據。
當用戶編輯好內容,點擊發送按鈕是調用sendMessage方法,發送數據,若是須要修改暱稱,則發送數據格式爲"/nick 暱稱"。
當服務器返回數據到客戶端,咱們經過appendLog方法對數據作處理,根據type字段,判斷是顯示用戶離線在線信息,仍是顯示聊天信息。最後更新在線人數。
【服務器端】
服務器端主要是接收信息,判斷是聊天信息仍是重命名信息,而後發送廣播。同時,當用戶鏈接上服務器端或者關閉鏈接時,服務器也會發送廣播通知其餘用戶。
- var WebSocket = require('ws');
- var WebSocketServer = WebSocket.Server,
- wss = new WebSocketServer({port: 8180});
- var uuid = require('node-uuid');
-
- var clients = [];
-
- function wsSend(type, client_uuid, nickname, message,clientcount) {
- for(var i=0; i<clients.length; i++) {
- var clientSocket = clients[i].ws;
- if(clientSocket.readyState === WebSocket.OPEN) {
- clientSocket.send(JSON.stringify({
- "type": type,
- "id": client_uuid,
- "nickname": nickname,
- "message": message,
- "clientcount":clientcount,
- }));
- }
- }
- }
-
- var clientIndex = 1;
-
- wss.on('connection', function(ws) {
- var client_uuid = uuid.v4();
- var nickname = "遊客"+clientIndex;
- clientIndex+=1;
- clients.push({"id": client_uuid, "ws": ws, "nickname": nickname});
- console.log('client [%s] connected', client_uuid);
-
- var connect_message = nickname + " 來了";
- wsSend("notification", client_uuid, nickname, connect_message,clients.length);
-
- ws.on('message', function(message) {
- if(message.indexOf('/nick') === 0) {
- var nickname_array = message.split(' ');
- if(nickname_array.length >= 2) {
- var old_nickname = nickname;
- nickname = nickname_array[1];
- var nickname_message = "用戶 " + old_nickname + " 更名爲: " + nickname;
- wsSend("nick_update", client_uuid, nickname, nickname_message,clients.length);
- }
- } else {
- wsSend("message", client_uuid, nickname, message,clients.length);
- }
- });
-
- var closeSocket = function(customMessage) {
- for(var i=0; i<clients.length; i++) {
- if(clients[i].id == client_uuid) {
- var disconnect_message;
- if(customMessage) {
- disconnect_message = customMessage;
- } else {
- disconnect_message = nickname + " 走了";
- }
-
- clients.splice(i, 1);
- wsSend("notification", client_uuid, nickname, disconnect_message,clients.length);
- }
- }
- }
- ws.on('close', function() {
- closeSocket();
- });
-
- process.on('SIGINT', function() {
- console.log("Closing things");
- closeSocket('Server has disconnected');
- process.exit();
- });
- });
咱們定義了wsSend函數用來處理消息的廣播。對每一個鏈接的用戶,咱們默認給他分配爲遊客。爲了實現廣播,咱們用clients數組來保存鏈接的用戶。