如何在Node.js WebSocket服务器中跟踪客户端的连接和断开连接?

huangapple go评论144阅读模式
英文:

how do I keep track of clients connecting and disconnecting in Node.js WebSocket Server?

问题

Sure, here's the translated content:

如何在Node.JS中使用'ws'模块跟踪用户连接和断开WebSocket服务器?我需要动态地添加和删除WebSocket到数组中,以便如果我需要向特定的WebSocket发送一些东西,我只需执行clients.send('blah blah blah')。有没有办法做到这一点?我已经尝试过但失败了。这是我尝试过的内容,这是我的'clients module':

clients = [];

function addClient(ws, wss, WebSocket) {
    clients.push(ws);
    console.log("Client Connect: " + clients.indexOf(ws) + ". " + clients.length + " Online")

    ws.on('message', function incoming(data, isBinary) {
        wss.clients.forEach(function each(client) {
            if(client != ws && client.readyState == WebSocket.OPEN) {
                const msg = isBinary ? data : data.toString();
                client.send(msg);
            }
        })
    })
    ws.onclose = function() {
        removeClient(ws);
    }
}

function removeClient(ws) {
    let indx = clients.indexOf(ws)
    clients = clients.splice(clients.indexOf(ws), 1)
    console.log("Client Disconnect: " + indx + ". " + clients.length + " Online")
}

module.exports = {
    clients, addClient, removeClient
}

每当WebSocket服务器接收到'connection'时,都会调用addClient。三个参数分别是:

  • ws - WebSocket(客户端)
  • wss - WebSocket服务器(我现在运行的代码)
  • WebSocket - 只是WebSocket模块的引用('ws')

这段代码基本正常工作,但容易出现问题。如果有人连接,该列表将将WebSocket添加到clients列表中。如果有人断开连接,有时会按预期将其删除,而其他时候则不会,会出现'ghost WebSocket'。我似乎找不到一个好的方法来实现这一点,所以我只是在寻求帮助。

当客户端连接时,将其添加到clients列表中,以便我可以通过索引向其发送内容。当客户端断开连接时,将其从列表中删除。

英文:

How do I keep track of users connecting and disconnecting from a WebSocket Server in Node.JS using the 'ws' module?

I need to dynamically add and remove the WebSockets to an array, so if I needed to send something to a specific WebSocket, I could just do clients.send('blah blah blah'),

Is there any way to do this? I have tried but failed. Here is what I have tried,

This is my 'clients module'

clients = [];

function addClient(ws, wss, WebSocket) {
    clients.push(ws);
    console.log("Client Connect: " + clients.indexOf(ws) + ". " + clients.length + " Online")

    ws.on('message', function incoming(data, isBinary) {
        wss.clients.forEach(function each(client) {
            if(client != ws && client.readyState == WebSocket.OPEN) {
                const msg = isBinary ? data : data.toString();
                client.send(msg);
            }
        })
    })
    ws.onclose = function() {
        removeClient(ws);
    }
}

function removeClient(ws) {
    let indx = clients.indexOf(ws)
    clients = clients.splice(clients.indexOf(ws), 1)
    console.log("Client Disconnect: " + indx + ". " + clients.length + " Online")
}


module.exports = {
    clients, addClient, removeClient
}

addClient is called whenever the WebSocket Server recieves 'connection'
The three arguments are:

  • ws - The WebSocket (Client)
  • wss - The WebSocket Server (Code that I am Running Right Now)
  • WebSocket - Just a reference to the WebSocket module ('ws')

This code works somewhat-normally, but breaks easily.
If someone connects, the list adds the websocket to the clients list.
If someone disconnects, it sometimes removes it as intended, and other times, it just doesn't, and there is a 'ghost websocket'

I can't seem to find a good way to achieve this, so I'm just asking for help.

When a client connects, add it to the clients list so I can send stuff to it by index.

When a client disconnects, remove it from the list.

答案1

得分: 0

在更多研究后,我了解到您可以为 WebSocket 分配任何属性或属性,这些属性将在整个生命周期内保持不变。我只是添加了一个永不减少且在有人连接时增加的计数器,并将一个id属性设置为该计数器。然后,我使用 array.filter 来过滤掉具有与断开连接的 WebSocket 相同id的客户端。

以下是代码:

clients = [];
aid = 0;

function addClient(ws, wss, WebSocket) {
    ws.userid = aid;
    aid += 1;
    clients.push(ws);

    console.log("Client Connect: " + ws.userid + ". " + clients.length + " Online");

    ws.on('message', function incoming(data, isBinary) {
        wss.clients.forEach(function each(client) {
            if (client !== ws && client.readyState === WebSocket.OPEN) {
                const msg = isBinary ? data : data.toString();
                client.send(msg);
            }
        });
    });

    ws.onclose = function () {
        removeClient(ws);
    };
}

function removeClient(ws) {
    clients = clients.filter((check) => {
        return check.userid !== ws.userid;
    });
    console.log("Client Disconnect: " + ws.userid + ". " + clients.length + " Online");
}

module.exports = {
    clients, addClient, removeClient
};

请注意,我没有翻译代码部分,只翻译了您的解释和注释。

英文:

After more research, I've learned that you can assign any attribute or property to a WebSocket that will stay throughout the entire lifecycle. I have simply added a counter that never goes down and increases when someone connects, and set an id attribute to that counter. I then use an array.filter to filter out the client with the id that the disconnecting WebSocket had.

Here is the code:

clients = [];
aid = 0;

function addClient(ws, wss, WebSocket) {
    ws.userid = aid;
    aid+=1;
    clients.push(ws)

    console.log("Client Connect: " + ws.userid + ". " + clients.length + " Online")

    ws.on('message', function incoming(data, isBinary) {
        wss.clients.forEach(function each(client) {
            if(client != ws && client.readyState == WebSocket.OPEN) {
                const msg = isBinary ? data : data.toString();
                client.send(msg);
            }
        })
    })

    ws.onclose = function() {
        removeClient(ws);
    }
}

function removeClient(ws) {
    clients = clients.filter((check) => {
        return check.userid != ws.userid
    })
    console.log("Client Disconnect: " + ws.userid + ". " + clients.length + " Online")
}


module.exports = {
    clients, addClient, removeClient
}

huangapple
  • 本文由 发表于 2023年8月11日 02:37:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76878499.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定