nodejs搭建一個webscoket服務器


最近技術支持工作中需要測試下websocket的問題,首先第一步,需要搭建一個服務器,沒有太多的經驗,只會點nodejs,於是用nodejs搭建了一個websocket的服務器。下面做個記錄:

前提,電腦中已經安裝了nodejs. 沒有安裝的看這里 http://nodejs.cn/

第一步,創建一個目錄,然后在該目錄下,執行下面的指令

npm init
npm install ws  //websocket 模塊
npm install uuid //隨機id模塊

 安裝完的目錄如下圖:

 

 

第二步,創建一個server.js文件,寫上如下的代碼:

//引入ws模塊
var WebSocket = require('ws');
//創建websocket服務,端口port為:****
var WebSocketServer = WebSocket.Server,
    wss = new WebSocketServer({ port: 8180 });

//引入uuid模塊
var uuid = require('uuid');

//定義一個空數組,存放客戶端的信息 
var clients = [];
//定義發送消息方法wsSend
//參數為 type:類型
//client_uuid:隨機生成的客戶端id
//nickname:昵稱
//message:消息
//clientcount:客戶端個數
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,
            }));
        }
    }
}
//聲明客戶端index默認為1 
var clientIndex = 1;
//服務端連接
wss.on('connection', function(ws) {
    //客戶端client_uuid隨機生成
    var client_uuid = uuid.v4();
    //昵稱為游客+客戶端index
    var nickname = "游客" + clientIndex;
    //client++
    clientIndex += 1;
    //將新連接的客戶端push到clients數組中
    clients.push({ "id": client_uuid, "ws": ws, "nickname": nickname });
    //控制台打印連接的client_uuid
    console.log('client [%s] connected', client_uuid);
    //聲明連接信息為 昵稱+來了
    // var connect_message = nickname + " 來了";
    var connect_message = " 來了";
    
    //服務器廣播信息 ***來了
    wsSend("notification", client_uuid, nickname, connect_message, clients.length);

    //當用戶發送消息時
    ws.on('message', function(message) {
        console.log("message", ArrayBufferUTF8ToStr(message));
        // 用戶輸入"/nick"的話為重命名消息
        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);
        }
    });

    //每個固定的時間 服務器給客戶端發送消息
    setInterval(() => {
        if(ws.readyState == ws.OPEN){
            let str = "服務器send"+Math.floor(Math.random()*100)
            var msg = Buffer.from( str);
            console.log(str);
            wsSend("message", client_uuid, nickname, msg, clients.length);
        }else{
            console.log("還沒有接通")
        }
        
        
    }, 3000);

    //關閉socket連接時
    var closeSocket = function(customMessage) {
        console.log("------關閉------")
        //遍歷客戶端
        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();
    });
});


function ArrayBufferUTF8ToStr(array) {
    var out,i,len,c;
    var char2,char3;
    if (array instanceof ArrayBuffer) {
        array = new Uint8Array(array);
    }

    out = "";
    len = array.length;
    i = 0;
    while(i < len) {
        c = array[i++];
        switch(c >> 4) {
            case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
                // 0xxxxxxx
                out += String.fromCharCode(c);
                break;
            case 12: case 13:
                // 110x xxxx   10xx xxxx
                char2 = array[i++];
                out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
                break;
            case 14:
                // 1110 xxxx  10xx xxxx  10xx xxxx
                char2 = array[i++];
                char3 = array[i++];
                out += String.fromCharCode(((c & 0x0F) << 12) |
                    ((char2 & 0x3F) << 6) |
                    ((char3 & 0x3F) << 0));
                break;
        }
    }

    return out;
}

  第三步,在該目錄下打開命令窗口,運行server.js文件啟動服務器

node server.js

  

另,貼上客戶端webscoket的代碼

class TestWebScoket2{
    private ws:egret.WebSocket;
    private ws_sendMessageTimer:egret.Timer;

    constructor(){
        this.init();

         //創建定時器 每100ms發送一次消息
         this.ws_sendMessageTimer =  new egret.Timer(1000,0);
         this.ws_sendMessageTimer.addEventListener(egret.TimerEvent.TIMER,this.onTimer,this);
        //  this.ws_sendMessageTimer.start();

    }
    private init(){
        this.ws = new egret.WebSocket();
        this.ws.type = egret.WebSocket.TYPE_STRING;
        this.ws.addEventListener(egret.Event.CONNECT,this.onOpen,this);
        this.ws.addEventListener(egret.ProgressEvent.SOCKET_DATA,this.onMessage,this);
        this.ws.addEventListener(egret.Event.CLOSE,this.onClose,this);
        this.ws.addEventListener(egret.IOErrorEvent.IO_ERROR,this.onError,this);
        this.ws.connect('10.0.1.215',8180);
    }

    private onOpen(evt:egret.Event){
        egret.log("ws鏈接成功");
        let cmd = "hello egret!";
        let ws = evt.target;
        // ws.writeUTF(cmd);
        
    }

    private onMessage(evt){
        console.log("-----------");
        
        let ws = evt.target;
        let msg = ws.readUTF();

        let obj = JSON.parse(msg);
        console.log(obj);
        let sound:egret.Sound = RES.getRes("bullet_mp3");
        sound.play(0,1);
        if(obj.type == "message"){
            egret.log(obj.nickname,this.ArrayBufferUTF8ToStr(obj.message.data));
            this.ws.writeUTF(this.ArrayBufferUTF8ToStr(obj.message.data));  
        }else if(obj.type == "notification"){
            egret.log(obj.nickname,obj.message)
        }
    }

    private onClose(evt){
        let ws = evt.target;
        egret.log("++++++++","鏈接關閉");
        this.ws_sendMessageTimer.stop();
    }

    private onError(err){
        egret.log("出現錯誤",err);
    }

    private onTimer(){
        this.ws.writeUTF("hello----"+Math.random()*100);
    }

    private ArrayBufferUTF8ToStr(array) {
        var out,i,len,c;
        var char2,char3;
        if (array instanceof ArrayBuffer) {
            array = new Uint8Array(array);
        }
    
        out = "";
        len = array.length;
        i = 0;
        while(i < len) {
            c = array[i++];
            switch(c >> 4) {
                case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
                    // 0xxxxxxx
                    out += String.fromCharCode(c);
                    break;
                case 12: case 13:
                    // 110x xxxx   10xx xxxx
                    char2 = array[i++];
                    out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
                    break;
                case 14:
                    // 1110 xxxx  10xx xxxx  10xx xxxx
                    char2 = array[i++];
                    char3 = array[i++];
                    out += String.fromCharCode(((c & 0x0F) << 12) |
                        ((char2 & 0x3F) << 6) |
                        ((char3 & 0x3F) << 0));
                    break;
            }
        }
    
        return out;
    }

}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM