Как переподключиться к веб-сокету - PullRequest
0 голосов
/ 15 апреля 2020

У меня проблемы с подключением к веб-сокету после прерывания потока.

Я не знаю root причину, по которой поток данных прерывается. Мой VPS-сервер работает постоянно, у меня есть inte rnet доступ к нему, есть другая программа, которая работает в то же время и не имеет проблем с сетью.

Но для каждого полученного пакета я увеличить мой счетчик i, и если я не изменился более 20 секунд, я пытаюсь восстановить соединение. Но любые попытки кода пока не увенчались успехом, он просто зацикливается и пытается восстановить соединение.

Nodejs, работающий на приличном linux сервере. Использование памяти или процессора во время отключения нормально. Разъединения не имеют закономерности, иногда запускаются в течение 2 дней без проблем, иногда отключаются 4 раза в день. Когда поток останавливается, единственный способ перезапустить это выйти из моего кода и запустить его снова, и он сразу же работает, поэтому никаких проблем на стороне сервера.

Мой код повторного подключения, который выполняется каждые 20 сек c ( который совпадает с моим исходным кодом подключения, за исключением дополнительной строки: const WebSocket = require ('ws');

//catch broken stream, if i is not changing, close and reconnect and alert through Telegram
if (i == prev_i) {
    ws.terminate();
    setTimeout(function() {
        console.log('waiting to reconnect');
        const ws = new WebSocket('wss://streamer.cryptocompare.com/v2?api_key=6f56....fe10');
        ws.on('open', function open() {
        ws.send('{"action": "SubAdd","subs": ["0~coineal~BTC~USDT"]}');
        });
    }, 10000);


    console.log("Reconnecting to stream");
    var strMessage = "Reconnecting to stream"
    var message = "chat_id=" + strChatId + "&text=" + strMessage
    var request = require('request');
    request.post({
      headers: {'content-type' : 'application/x-www-form-urlencoded'},
      url:     Url,
      body:    message
    }, function(error, response, body){
    });
}
prev_i = i;

edit 5.5.2020: согласно предложению ниже, я изменил свой код выше от

const ws = new WebSocket(...

до

ws = new WebSocket(...

Сегодня поток сбрасывается впервые после изменения. К сожалению, вместо попытки восстановить соединение в al oop, как раньше, выполнение кода остановлено с сообщениями консоли на прикрепленном рисунке. Строка 120 - это строка, которую я изменил. enter image description here

1 Ответ

0 голосов
/ 03 мая 2020

Я вижу одну проблему с вашим кодом: переменная ws затенена.

Когда вы делаете ws.terminate(), вы завершаете сокет, удерживаемый переменной ws в действующей области действия вокруг блока кода, который вы цитировали. Однако в коде, который вы передаете setTimeout для создания нового сокета, вы делаете const ws = new WebSocket(...]. Когда вы делаете это, вы объявляете новую переменную в области видимости, созданной анонимной функцией, которую вы передаете setTimeout. Эта переменная имеет то же имя, что и внешняя область, но отличается от от внешней. При назначении ему внешняя область действия ws не затрагивается. Итак, новый сокет создан, открыт, а затем ваш код забывает его. Так что, да, ваш код попытается снова подключиться.

Просто сбросьте const и используйте ws = new WebSocket(...). Очевидно, что для этого переменная ws, определенная во внешней области видимости, не может быть объявлена ​​с const ws. Он должен быть объявлен с let ws, или, что не так хорошо, var ws.

Я также рекомендовал бы обычно использовать линтер типа eslint, настроенный с разумным набором правила. eslint имеет правила для сообщения теневых переменных и предотвращения ошибок теневого копирования.

Кроме того, я бы рекомендовал использовать что-то вроде PWS вместо того, чтобы пытаться свернуть свой собственный код переподключения. Существуют все виды краевых корпусов с повторным подключением разъемов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...