I
I
itrushkoff2020-10-01 16:42:22
JavaScript
itrushkoff, 2020-10-01 16:42:22

Unity doesn't see disconnect from the server if another Unity calls it, any ideas?

Guys, help please :)
For the first time I'm doing something networked, and now I decided to make friends with the Unity client and the Nodejs server.
Subject: I start "play" in Unity - there is a connection to the server. I load a copy of this project through symbolic links, run "play" there - a second connection to the server occurs. In the serverObjects collection, 2 objects are seen, everyone is happy, everyone sees each other on both clients, the server fixes 2 connections. Then I disable one of the Unity projects (it doesn't matter by pressing "stop" or shutting down the entire project) - the server fixes the disconnect, but the remaining Unity does not react at all, as if it did not receive the shutdown event from the server at all. In the Unity log, the last message from the "register" event. "spawn" also worked. But here "rdisconnected" does not see at all, neither immediately, nor after a couple of minutes (I thought maybe some kind of timeout, which I don't know about).
Q: Any ideas how to fix this? And in passing - if there is a suspicion that this is due to the fact that the check goes through symbolic links (that is, in fact, the same project, perhaps with one id or address or something else), then how to really need to test network applications on Unity and in general?

Nodejs code:

var io = require('socket.io')(process.env.PORT || 52300);

// Custom classes
var Player = require('./Classes/Player.js');

console.log('Server has started');

var players = [];
var sockets = [];

io.on('connection', function(socket) {
  console.log('Connection made!');

  var player = new Player();

  players[player.id] = player;
  sockets[player.id] = socket;

  // Tell the client that this is our id for the server
  socket.emit('register', {
    id: player.id
  });
  socket.emit('spawn', player); // Tell myself i have spawned
  socket.broadcast.emit('spawn', player); // Tell others i have spawned

  // Tell myself about everyone else in the game
  for (var pID in players) {
    if (pID !== player.id) {
      socket.emit('spawn', players[pID]);
    }
  }

  socket.on('disconnect', function() {
    console.log('Player is disconnected');
    socket.broadcast.emit('rdisconnected', player);
    delete players[player.id];
    delete sockets[player.id];
  });
});


Code on the Unity client in the only component added to the stage:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using SocketIO;
using Project.Utility;

namespace Project.Networking {
  public class NetworkClient : SocketIOComponent {

    [Header("Network Client")]
    [SerializeField]
    private Transform networkContainer;

    private Dictionary<string, GameObject> serverObjects;

    // Start is called before the first frame update
    public override void Start() {
      base.Start();
      initialize();
      setupEvents();
    }

    // Update is called once per frame
    public override void Update() {
      base.Update();
    }

    private void initialize() {
      serverObjects = new Dictionary<string, GameObject>();
    }

    private void setupEvents() {
      On("open", (E) => {
        Debug.Log("Connection made to the server");
      });

      On("register", (E) => {
        string id = E.data["id"].ToString().RemoveQuotes();

        Debug.LogFormat("Our Client's ID ({0})", id);
      });

      On("spawn", (E) => {
        // Handling all spawning players
        string id = E.data["id"].ToString().RemoveQuotes();

        GameObject go = new GameObject("Server ID: " + id);
        go.transform.SetParent(networkContainer);
        serverObjects.Add(id, go);
      });

      On("rdisconnected", (E) => {
        string id = E.data["id"].ToString().RemoveQuotes();
        Debug.LogFormat("User {id} disconnected", id);

        //Destroy(serverObjects[id]); // Remove from game
        //serverObjects.Remove(id); // Remove from memory
        //Debug.LogFormat("Dictionary has {count} objects", serverObjects.Count);
      });
    }
  }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alex McArrow, 2020-10-02
@AlexMcArrow

According to documentation

// sending to all clients except sender
  socket.broadcast.emit('broadcast', 'hello friends!');

// sending to all connected clients
  io.emit('an event sent to all connected clients');

Try using io.emit to send user disconnect notification
socket.on('disconnect', function() {
    console.log('Player is disconnected');
    io.emit('rdisconnected', player);
    delete players[player.id];
    delete sockets[player.id];
  });

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question