nodejs搭建一个webscoket服务器【转】

最近技术支持工作中需要测试下websocket的问题,首先第一步,需要搭建一个服务器,没有太多的经验,只会点nodejs,于是用nodejs搭建了一个websocket的服务器。下面做个记录:

前提,电脑中已经安装了nodejs. 没有安装的看这里 http://nodejs.cn/

第一步,创建一个目录,然后在该目录下,执行下面的指令

1
2
npm init
npm install ws  //websocket 模块<br>npm install uuid //随机id模块

 安装完的目录如下图:

 

 

第二步,创建一个server.js文件,写上如下的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//引入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文件启动服务器

1
node server.js

  

另,贴上客户端webscoket的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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;
    }
 
}

https://www.cnblogs.com/thankspipi/p/15741220.html

posted on 2022-06-14 17:11  3D入魔  阅读(1576)  评论(0编辑  收藏  举报