WebSocket:如何在它死后自动重新连接

时间:2014-03-16 01:04:45

标签: javascript websocket

var ws = new WebSocket('ws://localhost:8080');
ws.onopen = function () {
  ws.send(JSON.stringify({
      .... some message the I must send when I connect ....
  }));

};

ws.onmessage = function (e) {
  console.log('Got a message')
  console.log(e.data);
};

ws.onclose = function(e) {  
  console.log('socket closed try again'); 

}

ws.onerror = function(err) {
  console.error(err)
};

当我第一次连接到套接字时,我必须首先向服务器发送一条消息来验证自己并订阅频道。

我遇到的问题是套接字服务器有时不可靠,会触发onerror对象的onclose'ws'事件。

问题:什么是一个好的设计模式,允许我,无论何时套接字关闭或遇到错误,等待10秒然后重新连接到套接字服务器(并重新发送到服务器的初始消息)

7 个答案:

答案 0 :(得分:51)

这是我最终的结果。它适用于我的目的。

function connect() {
  var ws = new WebSocket('ws://localhost:8080');
  ws.onopen = function() {
    // subscribe to some channels
    ws.send(JSON.stringify({
        //.... some message the I must send when I connect ....
    }));
  };

  ws.onmessage = function(e) {
    console.log('Message:', e.data);
  };

  ws.onclose = function(e) {
    console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason);
    setTimeout(function() {
      connect();
    }, 1000);
  };

  ws.onerror = function(err) {
    console.error('Socket encountered error: ', err.message, 'Closing socket');
    ws.close();
  };
}

connect();

答案 1 :(得分:2)

这对setInterval来说对我有用,因为客户端连接可能会丢失。

ngOnInit(): void {
    if (window.location.protocol.includes('https')) {
        this.protocol = 'wss';
    }

    this.listenChanges();
}


listenChanges(): void {
    this.socket = new WebSocket(`${this.protocol}://${window.location.host}/v1.0/your/url`);

    this.socket.onmessage = (event): void => {
        // your subscription stuff
        this.store.dispatch(someAction);
    };

    this.socket.onerror = (): void => {
        this.socket.close();
    };


    this.socket.onopen = (): void => {
        clearInterval(this.timerId);

        this.socket.onclose = (): void => {
            this.timerId = setInterval(() => {
                this.listenChanges();
            }, 10000);
        };
    };
}

打开套接字后,别忘了调用clearInterval

答案 2 :(得分:1)

原生Websocket api上方的包装太有趣了,无法很好地添加

https://github.com/joewalnes/reconnecting-websocket

答案 3 :(得分:1)

我发现这个包https://github.com/pladaria/reconnecting-websocket可以解决Websocket连接的重连问题。它具有可配置选项列表,其中之一是 reconnectionDelayGrowFactor,它决定了重新连接延迟的增长速度。

答案 4 :(得分:1)

如果套接字关闭或服务器上发生任何错误,则使用异步等待,客户端将永远每 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);

答案 5 :(得分:0)

这不是一个明确的反应问题,但这里是一个反应风格的答案:

TLDR:您可以使用 setInterval 定期检查 websocket 连接状态,并在连接关闭时尝试重新连接。 https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState

class TestComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};

    this.connect = this.connect.bind(this);
  }

  componentDidMount() {
    this.interval = setInterval(this.connect, 1000);
  }

  componentWillUnmount() {
    if (this.ws) this.ws.close();
    if (this.interval) clearInterval(this.interval);
  }

  connect() {
    // https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState
    if (this.ws === undefined || (this.ws && this.ws.readyState === 3)) {
      this.ws = new WebSocket(`ws://localhost:8080`);

      this.ws.onmessage = (e) => {
        console.log(JSON.parse(e.data));
      };
    }
  }

  render() {
    return <div>Hey!</div>;
  }
}

答案 6 :(得分:-3)

我发现了一个非常有用的生产解决方案。参考:

http://www.phpernote.com/html5/1370.html

  1. 检查网络是否可用:https://github.com/hubspot/offline
  2. 重新连接:https://github.com/joewalnes/reconnecting-websocket