Node.js 教程第十三篇——WebSocket

重溫 HTTP 協議

HTTP 協議能夠總結幾個特色:javascript

  • 一次性的、無狀態的短鏈接:客戶端發起請求、服務端響應、結束。
  • 被動性響應:只有當客戶端請求時才被執行,給予響應,不能主動向客戶端發起響應。
  • 信息安全性:得在服務器添加 SSL 證書,訪問時用 HTTPS。
  • 跨域:服務器默認不支持跨域,可在服務端設置支持跨域的代碼或對應的配置。

認識 TCP

TCP 協議能夠總結幾個特色:前端

  • 有狀態的長鏈接:客戶端發起鏈接請求,服務端響應並創建鏈接,鏈接會一直保持直到一方主動斷開。
  • 主動性:創建起與客戶端的鏈接後,服務端可主動向客戶端發起調用。
  • 信息安全性:一樣能夠使用 SSL 證書進行信息加密,訪問時用 WSS 。
  • 跨域:默認支持跨域。

認識 WebSocket

WebSocket 目前由 W3C 進行標準化。WebSocket 已經受到 Firefox 四、Chrome 四、Opera 10.70 以及Safari 5 等瀏覽器的支持。
若是在前端咱們能夠把 AJAX 請求看成一個 HTTP 協議的實現,那麼,WebSocket 就是 TCP 協議的一種實現。java

服務端 API

  • 安裝第三方模塊 ws:npm install ws
  • 開啓一個 WebSocket 的服務器,端口爲 8080
var socketServer = require('ws').Server;
var wss = new socketServer({
    port: 8080
});
  • 也能夠利用 Express 來開啓 WebSocket 的服務器
var app = require('express')();
var server = require('http').Server(app);

var socketServer = require('ws').Server;
var wss = new socketServer({server: server, port: 8080});
  • 用 on 來進行事件監聽
  • connection:鏈接監聽,當客戶端鏈接到服務端時觸發該事件
  • close:鏈接斷開監聽,當客戶端斷開與服務器的鏈接時觸發
  • message:消息接受監聽,當客戶端向服務端發送信息時觸發該事件
  • send: 向客戶端推送信息
wss.on('connection', function (client) {
    client.on('message', function (_message) {
        var _messageObj = JSON.parse(_message);
        //status = 1 表示正常聊天
        _messageObj.status = 1;
        this.message = _messageObj;
        //把客戶端的消息廣播給全部在線的用戶
        wss.broadcast(_messageObj);
    });

    // 退出聊天  
    client.on('close', function() {  
        try{
            this.message = this.message || {};
            // status = 0 表示退出聊天
            this.message.status = 0;
            //把客戶端的消息廣播給全部在線的用戶
            wss.broadcast(this.message);  
        }catch(e){  
            console.log('刷新頁面了');  
        }  
    });  
});

//定義廣播方法
wss.broadcast = function broadcast(_messageObj) {  
    wss.clients.forEach(function(client) { 
        client.send(JSON.stringify(_messageObj))
    });  
};

客戶端 API

  • 在支持 WebSocket 的瀏覽器下實例化 WebSocket ,參數爲 WebSocket 服務器地址,創建與服務器的鏈接
if(!WebSocket){
    $('.connState').text("您的瀏覽器不支持WebSocket");
    return false;
} 
//鏈接 socket 服務器
var socket = new WebSocket('ws://localhost:8080');
  • onopen:當網絡鏈接創建時觸發該事件
//監聽 socket 的鏈接
socket.onopen = function(){
    $('.connState').text("服務已鏈接 ws://localhost:8080");
}
  • onclose:當服務端關閉時觸發該事件
//監聽服務端斷開
socket.onclose = function(){
    $('.connState').text("服務已斷開");
    socket = null;
}
  • close: 在客戶端斷開與服務端的鏈接 socket.close();
  • onerror:當網絡發生錯誤時觸發該事件
//監聽服務端異常
socket.onerror = function(){
    $('.connState').text("服務錯誤");
    socket = null;
}
  • onmessage:當接收到服務器發來的消息的時觸發的事件,也是通訊中最重要的一個監聽事件
//監聽服務端廣播過來的消息
socket.onmessage = function(msg){
    var msgObj = JSON.parse(msg.data);
    if(msgObj.status == 0){
        $('<p>' + msgObj.nickname + '[' + msgObj.time + ']退出聊天</p>').appendTo('.msgList');
    } else{
        $('<p>' + msgObj.nickname + '[' + msgObj.time + ']:' + msgObj.message + '</p>').appendTo('.msgList');
    }
}
  • send:向服務端推送消息
var sendMessage = function(_mess){
    if(socket){
        var myDate = new Date();
        var now = myDate.getMonth() + '-' + myDate.getDate() + ' ' + myDate.getHours() + ':' + myDate.getMinutes() + ':' + myDate.getSeconds();                
        
        var mesObj = {
            nickname: $('#nickName').val(),
            message: _mess || $('#mesBox').val(),
            time: now
        }
        //向服務端發送消息
        socket.send(JSON.stringify(mesObj));
    }            
}

項目應用

該案例是一個多人聊天室node

運行步驟express

  • npm install ws
  • node socketServer

案例思路npm

  • 服務端開戶一個服務 new socketServer({port: 8080});
  • 客戶端創建和服務端的鏈接 var socket = new WebSocket('ws://localhost:8080');
  • 創建鏈接的同時發送上線信息給服務端 socket.send('加入聊天');
  • 服務端接受到客戶端的消息觸發 message 方法,而後將該消息廣播給全部在線的用戶
  • 全部客戶端收到來自服務端廣播的消息,而後將該消息顯示在聊天列表。
  • 聊天和退出聊天都是重複着客戶端發送消息,服務端接受消息而後向客戶端廣播消息,客戶端顯示廣播消息。
相關文章
相關標籤/搜索