Повторное подключение Socket.io срабатывает независимо от того, что я делаю

Использование socket.io 1.4.5.

Кажется, что бы я ни делал, я не могу предотвратить запуск socket.io события переподключения или уничтожение клиентского сокета при прерывании интернет-соединения.

На стороне клиента у меня: reconnectionDelay: 99999999, timeout: 99999999999, reconnection: false,

И все же, если Интернет отключается, сокет становится неопределенным (примерно через 20 секунд), и событие повторного подключения срабатывает, когда Интернет снова включается.

Моя конечная цель - использовать один и тот же сокет на сервере и на клиенте (независимо от того, сколько времени прошло с тех пор, как они общались), если этот сокет явно не отключен на сервере. Я не могу повторно подключиться к сокету по своему желанию, потому что я храню данные в сокете и широко использую socket.id в своем приложении. ЕСЛИ сокет и идентификатор сокета внезапно изменятся, приложение сломается.


person Chris Scott    schedule 19.06.2017    source источник
comment
Похоже, вам нужен клиентский сеанс, основанный на файле cookie, когда сокет подключается, а не пытается создать постоянный объект сокета. Затем вы сохраняете информацию в этом сеансе, к которому вы можете подключиться в любое время, когда от этого клиента приходит новое соединение сокета.   -  person jfriend00    schedule 19.06.2017


Ответы (1)


Я думаю, вам нужно передать какую-то уникальную переменную при рукопожатии и сохранить данные по этой переменной. Регенерация socket.id является нормальным поведением socket.io.

В моей практике я делаю начальный запрос к серверу, чтобы создать переменную slot и сохранить ее коллекцию slots в mongodb, а после создания соединения я определяю эту переменную slot как рукопожатие.

или давайте просто упростим ответ на Ваш вопрос и используем: https://www.npmjs.com/package/express-socket.io-session

также немного «взломать» использование логики пространств имен: https://socket.io/docs/rooms-and-namespaces/#custom-namespaces



БОНУС:

вот быстрое решение:

сторона клиента:

function genUUID() {
    var d = new Date().getTime();
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = (d + Math.random()*16)%16 | 0;
        d = Math.floor(d/16);
        return (c=='x' ? r : (r&0x3|0x8)).toString(16);
    });
    return uuid;
};

var namespace = localStorage.getItem("namespace");
if(!namespace) {
  namespace = genUUID();
  localStorage.setItem("namespace", namespace);
}

var connect = function (ns) {
    return io.connect(ns, {
       query: 'ns='+ns   // this is handshake variable `ns`
    });
}

var socket = connect('/'+namespace);

серверная часть:

const 
  url = require('url'),
  sharedData = {};

io.sockets.on('connection', (socket) => {
  const handshake = url.parse(socket.handshake.url, true);
  const ns = handshake.query ? handshake.query.ns : 'default';
  console.log('GOT CONNECTION TO NS: '+ns);

  io.of(ns).on('connection', (socket) => {
    if(!sharedData[ns]) sharedData[ns] = {};
    // put socket code here
    socket.on('some-event', (data) => {
      sharedData[ns]['some-event'] = data.someData;
    });
  });
});
person num8er    schedule 19.06.2017
comment
к сожалению, все мое приложение, как клиент, так и сервер, основано на использовании socket.id в качестве уникального идентификатора. Переписывать это было бы болезненным опытом. конечно, должен быть какой-то способ сохранить исходный сокет как на клиенте, так и на сервере даже после повторного подключения. - person Chris Scott; 19.06.2017
comment
Есть 2 варианта: 1. переписать свой код, 2. переписать код socket.io-client. Выберите один из них (: - person num8er; 19.06.2017
comment
Вы можете объяснить то, на что вы ссылались? На странице товара нет описания, только инструкция по установке. Я предполагаю, что это какой-то обработчик сеанса для сокета? Как это поможет сохранить мои сокеты? - person Chris Scott; 19.06.2017
comment
В ссылке, которую я Вам дал, внизу есть пример с рукопожатием. Это упрощает процесс создания и обработки этой переменной slot, которую я использую вручную, сохраняя контекст сеанса. - person num8er; 19.06.2017
comment
Я не ищу примеров. Я ищу краткий обзор или описание того, что этот проект делает и для чего. - person Chris Scott; 19.06.2017
comment
просто: он создает объект socket.handshake.session, который может хранить данные и перечитывать их при повторном подключении. - person num8er; 19.06.2017
comment
хм, спасибо, может быть полезно, но похоже, что мне придется много переписывать, несмотря ни на что. - person Chris Scott; 19.06.2017
comment
хорошо, я обновил свой ответ, проверьте его. Идея состоит в том, чтобы создать динамически хэшируемое пространство имен и просто отслеживать его внутри пространства имен. это единственная стабильная ручная вещь, которую Вы можете взять под свой контроль - person num8er; 19.06.2017
comment
есть ли способ просто не иметь тайм-аут соединения, поэтому, если интернет отключится, а затем снова включится, он будет повторно использовать старый сокет, несмотря ни на что? Меня не волнует, вызовет ли это проблемы с производительностью, я могу понять, как вручную отключить сокеты, которые фактически навсегда отключены. полное отключение тайм-аутов соединения было бы самым простым решением. - person Chris Scott; 19.06.2017
comment
@ChrisScott Я добавил в свой ответ БОНУСНУЮ часть, в которой показан пример использования пространств имен в качестве группировки socket.id. - person num8er; 19.06.2017