Websocket 检测客户端断开连接失败

Websocket detect client disconnect fails

我正在使用以下逻辑来验证客户端是否连接到 websocket:客户端不断向服务器发送 ping。服务器超时会在完成时触发事件。一旦客户端 ping 服务器,服务器超时就会重置。当连接一个客户端时,这工作正常。但是逻辑在多个客户端上中断了。我怎样才能解决这个问题?一旦第二个客户端连接,服务器就说客户端 1 已断开连接,并且当两个客户端断开连接时不打印任何内容。

这是我的服务器逻辑:

const WebSocket = require("ws");
const express = require("express");
const app = express();
const server = require("http").createServer(app);
const url = require('url');

const PORT = process.env.PORT || 3000;

const wss = new WebSocket.Server({ server: server });
app.get("/", (req, res) => res.send("Temst."));

var tm;

function ping(client) {
  tm = setTimeout(function () {
    console.log(`[-] ${client} Disconnected`);
    wss.emit("customClose", client);
  }, 5000);
}

function pong(client) {
  clearInterval(tm);
  // console.log("[!] Cleared timeout");
  ping(client);
}

wss.on("connection", function connection(ws, req) {
  var queryData = url.parse(req.url,true).query;
  ping(queryData.id);
  console.log(`[+] ${req.socket.remoteAddress} Connected`);

  wss.clients.forEach(function each(client) {
    if (client.readyState === WebSocket.OPEN) {
      message = {
        type: "alert",
        msg: `${queryData.id} has Connected.`,
      };
      client.send(JSON.stringify(message), { binary: false });
    }
  });

  ws.on("message", function incoming(message) {
    if (message == "__ping__") {
      console.log(`[!] Ping Receieved from ${req.socket.remoteAddress}`);
      pong(queryData.id);
    } else {
      `[!] Message Receieved from ${req.socket.remoteAddress}`;
     
      wss.clients.forEach(function each(client) {
        if (client.readyState === WebSocket.OPEN) {
          client.send(msg, { binary: false });
        }
      });
    }
  });
});

wss.addListener("customClose", function (m) {
  wss.clients.forEach(function each(client) {
    if (client.readyState === WebSocket.OPEN) {
      message = {
        type: "alert",
        msg: `${m} has Disconnected.`,
      };
      client.send(JSON.stringify(message), { binary: false });
    }
  });
});

server.listen(PORT, () => console.log("Listening on port 3000"));


我想我已经解决了问题。查看 ws 包文档后,我尝试了服务器端 ping 而不是客户端。它目前正在为多个用户工作。有问题会更新。

const WebSocket = require("ws");
const express = require("express");
const app = express();
const server = require("http").createServer(app);
const url = require("url");

const PORT = process.env.PORT || 3000;

const wss = new WebSocket.Server({ server: server });
app.get("/", (req, res) => res.send("Temst."));

var myClients = [];

wss.on("connection", function connection(ws, req) {
  var queryData = url.parse(req.url, true).query;
  myClients.push({
    id: queryData.id,
    wsoc: ws,
    isAlive: true,
  });

  console.log(`[+] ${req.socket.remoteAddress} Connected`);

  wss.clients.forEach(function each(client) {
    if (client.readyState === WebSocket.OPEN) {
      message = {
        type: "alert",
        msg: `${queryData.id} has Connected.`,
      };
      client.send(JSON.stringify(message), { binary: false });
    }
  });

  ws.on("pong", () => {
    let x = myClients.find((o) => o.wsoc === ws);
    x.isAlive = true;
  });

  ws.on("message", function incoming(message) {
    console.log(`[!] Message Receieved from ${req.socket.remoteAddress}`);
    msg = JSON.parse(message);
    console.log(queryData);
    msg = { ...msg, time: new Date().toISOString() };
    wss.clients.forEach(function each(client) {
      if (client.readyState === WebSocket.OPEN) {
        client.send(JSON.stringify(msg), { binary: false });
      }
    });
  });
});

wss.addListener("customClose", function (m) {
  wss.clients.forEach(function each(client) {
    if (client.readyState === WebSocket.OPEN) {
      message = {
        type: "alert",
        msg: `${m} has Disconnected.`,
      };
      client.send(JSON.stringify(message), { binary: false });
    }
  });
});

const interval = setInterval(function ping() {
  myClients.forEach((clnt, index) => {
    if (clnt.isAlive === false) {
      console.log("[-]", clnt.id, "has Disconnected.");
      wss.emit("customClose", clnt.id);
      clnt.wsoc.terminate();
      myClients.splice(index, 1);
    }
    clnt.isAlive = false;
    clnt.wsoc.ping();
  });
}, 5000);

server.listen(PORT, () => console.log("Listening on port 3000"));