NodeJS Websocket服务器重启时如何重新连接

时间:2013-10-30 19:20:41

标签: node.js websocket

在Node.js中我使用websockets/ws进行WebSocket连接。以下是客户端的代码。假设我们连接的服务器套接字停机了一分钟。 close事件将触发,但是每当服务器上的套接字出现故障或错误时,重新连接到套接字的最佳方法是什么?

var ws = new WebSocket('ws://localhost');

ws.on('open', function() {
    console.log('socket open');
});
ws.on('error', function() {
    console.log('socket error');
    // how do I reconnect to the ws after x minutes here?
});
ws.on('close', function() {
    console.log('socket close');
    // how do I reconnect to the ws after x minutes here?
});

5 个答案:

答案 0 :(得分:28)

试试这个:

var reconnectInterval = x * 1000 * 60;
var ws;
var connect = function(){
    ws = new WebSocket('ws://localhost');
    ws.on('open', function() {
        console.log('socket open');
    });
    ws.on('error', function() {
        console.log('socket error');
    });
    ws.on('close', function() {
        console.log('socket close');
        setTimeout(connect, reconnectInterval);
    });
};
connect();

您可以使用原始实现而无需将其包装。

答案 1 :(得分:12)

我已成功使用https://github.com/joewalnes/reconnecting-websocket/blob/master/reconnecting-websocket.js

你应该可以这样做:

ws = new ReconnectingWebSocket('ws://....');
ws.reconnectInterval = 60000; // try to reconnect after 10 seconds

答案 2 :(得分:8)

2018-Jan update

重新连接到断开连接的Web套件non-trivial, and best delegated to a library。目前用于此目的的最小且最积极维护的库是reconnecting-websocket,其中obsoletes joewalnes's library来自另一个答案。特别是对于Node.js,您需要传递构造函数,例如WebSocket:

import WebSocket from 'ws';
import ReconnectingWebSocket from 'reconnecting-websocket';
const ws = new ReconnectingWebSocket('wss://some-feed.com', [], {
  constructor: WebSocket,
  connectionTimeout: ...,  // in milliseconds
  reconnectInterval: ...,
});

答案 3 :(得分:2)

您应该考虑迁移到socket.io

  1. 具有内置的自动重新连接功能。而且您不必为此做任何事情。默认情况下已启用它。
  2. 令人惊讶的是,它与旧版浏览器兼容,甚至不支持本机websocket的浏览器。

两者的代码非常相似,但是socket.io可能短一些。例如对于服务器代码,我们过去通常是这样写的:

const WebSocketServer = require('websocket').server
const ws = new WebSocketServer({ httpServer });
ws.on('request', (request) => onConnection(request));

function onConnectionRequest(request) {
  const connection = request.accept(null, request.origin);
  if (!connection) return;
  connection.on('message', (msg) => onMessageReceived(msg));
  connection.on('close', () => onConnectionClosed());
}

function onMessage(message) {
  if (message.type === 'utf8') {
    const data = message.utf8Data;
    const request = JSON.parse(data);
    // todo use request
  }
}

Socket.io代码非常相似,但略短一些。

const io = require('socket.io')(httpServer);
io.on('connection', (socket) => onConnection(socket));

function onConnection(socket) {
  socket.on('message', (msg) => onMessage(msg));
  socket.on('disconnect', (reason) => onDisconnect(reason));
}

function onMessage(request) {
  // todo use request
}

但是请记住,还必须重写客户端代码。 例如对于Angular,我使用ngx-socket-io插件,从而极大地简化了代码。

答案 4 :(得分:0)

如果套接字关闭或服务器上发生任何错误,则使用异步等待,客户端将永远每 5 秒尝试自动连接一次

"use strict";

var ws = require("ws");
var url = 'ws://localhost:3000';
var openedSocket = null;
var timeInterval = 5000;

function connect() {
  var client = new ws(url);
  return new Promise((resolve, reject) => {
    console.log("client try to connect...");

    client.on("open", () => {
      console.log(
        "WEBSOCKET_OPENED: client connected to server at port %s", port);
      openedSocket = true;
      resolve(openedSocket);
    });

    client.on("message", (data) => {
      console.log(data);
    });

    client.on("close", (err) => {
      console.log("WEBSOCKET_CLOSE: connection closed %o", err);
      openedSocket = false;
      reject(err);
    });

    client.on("error", (err) => {
      console.log("WEBSOCKET_ERROR: Error", new Error(err.message));
      openedSocket = false;
      reject(err);
    });
  });
}

async function reconnect() {
  try {
    await connect();
  } catch (err) {
    console.log("WEBSOCKET_RECONNECT: Error", new Error(err.message));
  }
}

reconnect();

// repeat every 5 seconds
setInterval(() => {
  if (openedSocket == false) {
    reconnect();
  }
}, timeInterval);