node.jssocketssocket.ioreconnect

Socket disconnect, socket reconnect


I have found this question multiple times, but I'm not being able to make it work...

The system is a multiplayer online game where I need to disconnect the client and reconnect it within the same function as player respawns, here is what I'm doing:


Client:

I'm making the initial connection with:

var socket = io();

At some point, I'm checking the connection inside a loop with:

console.log(socket);

Which returns:

n {io: n, nsp: "/", json: n, ids: 812, acks: {…}, …}
  acks: {840: ƒ, 841: ƒ, 842: ƒ, 843: ƒ, 844: ƒ, 845: ƒ, 846: ƒ, 847: ƒ, 848: ƒ, 849: ƒ, 850: ƒ, 851: ƒ}
  connected: true
  disconnected: false
  id: "ucS-fRqvhc_3OlYZAAAC"
  ids: 852
  io: n {nsps: {…}, subs: Array(6), opts: {…}, _reconnection: true, _reconnectionAttempts: Infinity, …}
  json: n {io: n, nsp: "/", json: n, ids: 852, acks: {…}, …}
  nsp: "/"
  receiveBuffer: []
  sendBuffer: []
  subs: (3) [{…}, {…}, {…}]
  _callbacks: {$connecting: Array(1), $connect: Array(1), $update: Array(1), $dialogo-servidor-usuarios: Array(1), $simon-says: Array(1)}
  __proto__: Object

Finally, I'm doing the disconnect inside a method, like this:

socket.disconnect();

Server

socket.on('disconnect', function() {
      //socket.reconnect();
      //buscamos el nombre del usuario por el id del sock
      var player = game.all_player_info(socket.id);
      if (player != null) {
          //revisamos
          console.log(player);
          //armamos el pedido
          req = API_URI;
          req += '?model=user/close';
          req += '&username=';
          req += player.name;
          //no usamos el password del usuario, sino el de la aplicación.
          req += '&password='
          req += player.pass;

          //lo marcamos offline de nuevo.
          request(req, { json: true }, (err, res, body) => {
          //en caso de error de comunicación
          if (err) { return console.log(err); }
          //feedback de API
          console.log(body);
          });

          //hacemos el player quede en campo 10 segundos de espera
          setTimeout( function() {
              //cuando pasen 5'
              console.log(req);
              //removemos la unidad
              game.removePlayer(socket.id);
          }, 8000 );
      }
  });

I've tried using "socket.socket.reconnect()", I've tried using "socket.reconnect()" by itself as well... still can't make it work. Probably just tired once again, but I'm not sure where or what I'm doing wrong here.

So far the server and the client are both running on 127.0.0.1:443

console.log(socket.io), in the client returns:

io: n
autoConnect: true
backoff: r {ms: 1000, max: 5000, factor: 2, jitter: 0.5, attempts: 0}
connecting: [n]
decoder: s {reconstructor: null, _callbacks: {…}}
encoder: n {}
encoding: false
engine: n {secure: true, agent: false, hostname: "127.0.0.1", port: "443", query: {…}, …}
lastPing: Sun Sep 30 2018 12:35:16 GMT-0300 (hora estándar de Argentina) {}
nsps: {/: n}
opts: {path: "/socket.io", hostname: "127.0.0.1", secure: true, port: "443"}
packetBuffer: []
readyState: "open"
skipReconnect: false
subs: (6) [{…}, {…}, {…}, {…}, {…}, {…}]
uri: "https://127.0.0.1"
_callbacks: {$open: Array(1), $packet: Array(1), $close: Array(1)}
_randomizationFactor: 0.5
_reconnection: true
_reconnectionAttempts: Infinity
_reconnectionDelay: 1000
_reconnectionDelayMax: 5000
_timeout: 20000

Any advice is welcome! Thanks!


Solution

  • It might be a lot easier to just move your server code for connect and disconnect into separate functions. Call those functions on connect and disconnect. So far, still the same logic you already have, just different code structure.

    Then, create a socket.io message respawn where you call your two functions (the first one to shut down the user, the second one to respawn them). That will let you respawn without actually reconnecting the socket.io connection and avoid the issues you're having now with reconnecting the socket.io connection.

    Note, you should probably also modify your disconnect code so that it returns a promise that resolves when it is done so you can call your connect logic only after the disconnect logic has completed.

    Then, all the client would have to do is:

    socket.emit('respawn');