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