【问题标题】:How can I do Ping/Pong between JavaScript and NodeJS WebSocket?如何在 JavaScript 和 NodeJS WebSocket 之间进行 Ping/Pong?
【发布时间】:2020-07-12 09:33:03
【问题描述】:

我目前正在开发一个 NodeJS WebSocket 服务器。为了检测断开的连接,我在这里遵循了本指南:

https://github.com/websockets/ws#how-to-detect-and-close-broken-connections

服务器端运行良好,但客户端出现问题,因为我找不到 ping 功能。

有没有人知道如何在没有库的情况下完成客户端部分?

const WebSocket = require('ws');

function heartbeat() {
  clearTimeout(this.pingTimeout);

  // Use `WebSocket#terminate()`, which immediately destroys the connection,
  // instead of `WebSocket#close()`, which waits for the close timer.
  // Delay should be equal to the interval at which your server
  // sends out pings plus a conservative assumption of the latency.
  this.pingTimeout = setTimeout(() => {
    this.terminate();
  }, 30000 + 1000);
}

const client = new WebSocket('wss://echo.websocket.org/');

client.on('open', heartbeat);
client.on('ping', heartbeat);
client.on('close', function clear() {
  clearTimeout(this.pingTimeout);
});

一个主要问题是我认为没有 ping 方法:

client.on('open') -> client.onopen available in JavaScript
client.on('close') -> client.onclose available in JavaScript
client.on('ping') -> How? Just how?

【问题讨论】:

标签: javascript node.js


【解决方案1】:

遗憾的是,对于ping frame,API 不支持它,如前面的答案所述。

最流行的解决方法是监听关闭事件并尝试使用间隔重新连接到服务器。

This tutorial 易于理解并包含大多数以 WS 开头的用例:

var ws = new WebSocket("ws://localhost:3000/ws");
let that = this; // cache the this
var connectInterval;
var check = () => {
    const { ws } = this.state;
    if (!ws || ws.readyState == WebSocket.CLOSED) this.connect(); //check if websocket instance is closed, if so call `connect` function.
};

// websocket onopen event listener
ws.onopen = () => {
    console.log("connected websocket main component");

    this.setState({ ws: ws });
    that.timeout = 250; // reset timer to 250 on open of websocket connection 
    clearTimeout(connectInterval); // clear Interval on on open of websocket connection
};

// websocket onclose event listener
ws.onclose = e => {
    console.log(
        `Socket is closed. Reconnect will be attempted in ${Math.min(
            10000 / 1000,
            (that.timeout + that.timeout) / 1000
        )} second.`,
        e.reason
    );

    that.timeout = that.timeout + that.timeout; //increment retry interval
    connectInterval = setTimeout(this.check, Math.min(10000, that.timeout)); //call check function after timeout
};

// websocket onerror event listener
ws.onerror = err => {
    console.error(
        "Socket encountered error: ",
        err.message,
        "Closing socket"
    );
    ws.close();
};

【讨论】:

    【解决方案2】:

    我认为您在客户端上寻找的是onmessage

    client.onmessage = function (event) {
      console.log(event.data);
    }
    

    从服务器发送的所有消息都可以通过这种方式收听。见https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications

    【讨论】:

      【解决方案3】:

      没有用于发送 ping 帧或接收 pong 帧的 Javascript API。您的浏览器要么支持,要么不支持。也没有 API 可以启用、配置或检测浏览器是否支持和使用 ping/pong 帧。

      https://stackoverflow.com/a/10586583/7377682

      【讨论】:

        猜你喜欢
        • 2019-03-16
        • 2020-12-29
        • 2020-09-12
        • 2017-04-30
        • 1970-01-01
        • 2019-07-17
        • 1970-01-01
        • 2012-05-22
        • 1970-01-01
        相关资源
        最近更新 更多