Users being disconnected

Options
Hello all. I have a game set up so that there is a server-side Unity application that must first be running in order for client-side users to log-in; the user sends a load request to the server-side application in order to retrieve the player's relevant information. The first user that logs in connects perfectly; there are no problems whatsoever. However, when a second user connects, the first player client is disconnected. This does not happen when I run the server-side application and multiple client applications locally on the same machine; this only happens when the clients are connecting from other machines. What might be causing this? Any suggestions would be greatly appreciated.

Comments

  • Tobias
    Options
    The possible causes for this are infinite. You will have to try to find out more about the causes yourself, so:
    Have a look at the server logs.
    Have a look at the client logs.
    Adjust the debug output as needed to find out more.
    Debug a client and check for exceptions or other issues you might miss.
  • On further inspection, it appears as though users are being disconnected due to a force disconnection line of code I typed in myself. However, that should only be called for users that attempt to log-in with a username that is already being used by someone within the game; it is being called every time a second client logs in, regardless of what that user's name is, and the *first* client is the one being disconnected. This leads me to believe there is something wrong with how I'm getting the originating player's actorNumber and using that to send information, even though I used the RealTime demo that came with Photon as a starting point (Users pretty much connect the same way), and, again, things work perfectly when all of the client applications are run on the same machine as the admin application. Here is the relevant code from the admin application, in its PhotonGame class:

    [code2=csharp]public override void OnEvent(EventData photonEvent)
    {
    print ("PHOTON EVENT: " + photonEvent.ToString());
    base.OnEvent(photonEvent);

    Hashtable evData = null;

    evData = photonEvent[(byte)LiteEventKey.CustomContent] as Hashtable;

    int originatingActorNr = 0;
    if (photonEvent.Parameters.ContainsKey((byte)LiteEventKey.ActorNr))
    {
    originatingActorNr = (int)photonEvent[(byte)LiteEventKey.ActorNr];
    }

    PhotonPlayer originatingPlayer;
    this.Players.TryGetValue(originatingActorNr, out originatingPlayer);

    switch (photonEvent.Code)
    {
    #region LiteEventCode
    case (byte)LiteEventCode.Join:
    int[] actorsInGame = (int[])photonEvent[(byte)LiteEventKey.ActorList];
    foreach (int i in actorsInGame)
    {
    if (!this.Players.ContainsKey(i))
    {
    GameObject newPlayer = new GameObject();
    newPlayer.name = "Remote Player" + i.ToString();
    newPlayer.tag = "RemotePlayer";
    newPlayer.AddComponent(typeof(PhotonPlayer));

    PhotonPlayer NewPlayer = newPlayer.GetComponent <PhotonPlayer>();
    NewPlayer.Initialize(i);
    this.Players = NewPlayer;
    }
    }
    break;

    case (byte)LiteEventCode.Leave:
    PhotonPlayer p = this.Players[originatingActorNr];
    this.Players.Remove(originatingActorNr);
    Destroy (p.gameObject);
    break;[/code2]

    This is the case in my OnEvent function in the admin application that handles new players entering. When a player logs in, the player also sends a load request to the admin application; in my OnEvent function, the code that handles the load request is as follows:

    [code2=csharp]case (byte)PhotonEventCodes.EventCode.LoadRequest:
    string nm = (string)evData[(byte)PhotonEventCodes.PlayerEventKey.PlayerName];
    bool alreadyOnline = false;
    print ("LoadRequest received.");

    //Ensure that the player is not already online
    foreach (KeyValuePair<int,PhotonPlayer> kvp in Players)
    {
    if (kvp.Value.PlayerName == nm)
    {
    alreadyOnline = true;
    }
    }
    if(!alreadyOnline)
    {
    //Send information pertaining to the player to the client
    //Send information pertaining to the world to the client
    int[] targetActors = new int[1];
    targetActors[0] = originatingPlayer.actorNr;
    Peer.OpRaiseEvent((byte)PhotonEventCodes.EventCode.LoadSuccessful,null,true,1,targetActors);
    }
    else
    {
    SendForceDisconnect(originatingPlayer,"That player is already logged in.");
    }
    break;[/code2]

    On the client side application, here is the load request that the player sends.

    [code2=csharp]internal void SendLoadRequest(LitePeer peer)
    {
    if (peer == null)
    {
    return;
    }
    print ("Sending load request for " + PlayerName);
    Hashtable evInfo = new Hashtable();
    evInfo.Add ((byte)PhotonEventCodes.PlayerEventKey.PlayerName,PlayerName);
    loading = true;
    int[] targetActors = new int[1];
    targetActors[0] = 1;
    peer.OpRaiseEvent((byte)PhotonEventCodes.EventCode.LoadRequest,evInfo,true,0,targetActors);
    }[/code2]

    This is called when the client connects, in the client's own OnEvent function in its own PhotonGame class:

    [code2=csharp]public override void OnEvent(EventData photonEvent)
    {
    base.OnEvent(photonEvent);

    Hashtable evData = null;
    // if (photonEvent.Parameters.ContainsKey(LiteEventKey.CustomContent))
    // {
    evData = photonEvent[(byte)LiteEventKey.CustomContent] as Hashtable;
    // }

    int originatingActorNr = 0;
    if (photonEvent.Parameters.ContainsKey((byte)LiteEventKey.ActorNr))
    {
    originatingActorNr = (int)photonEvent[(byte)LiteEventKey.ActorNr];
    }

    PhotonPlayer originatingPlayer;
    this.Players.TryGetValue(originatingActorNr, out originatingPlayer);

    GameObject loadScreen;

    switch (photonEvent.Code)
    {
    #region LiteEventCode
    case (byte)LiteEventCode.Join:
    int[] actorsInGame = (int[])photonEvent[(byte)LiteEventKey.ActorList];

    foreach (int i in actorsInGame)
    {
    if (!this.Players.ContainsKey(i))
    {
    GameObject newPlayer = new GameObject();
    newPlayer.name = "Local Player" + i.ToString();
    newPlayer.tag = "RemotePlayer";
    newPlayer.AddComponent(typeof(PhotonPlayer));

    PhotonPlayer NewPlayer = newPlayer.GetComponent <PhotonPlayer>();
    NewPlayer.Initialize(i);
    this.Players = NewPlayer;
    }
    }
    this.PrintPlayers();

    this.LocalPlayer.SendLoadRequest(this.Peer);
    //this.LocalPlayer.SendInfo(Peer);
    break;[/code2]

    What might I be doing wrong, here? I'm fairly certain that it has something to do with the information not being sent to the appropriate actor numbers, but if that's the case, why would it work perfectly when everything is run on the local machine? Any help would be greatly appreciated.
  • At a first glance, I don't see any obvious errors in your code, sorry. The only way to sort this out is to add more debug logging or attach a debugger and step through your work flow. Check what's in your "Players" collection, if the events & operations contain the data you expect and so on. Good luck!
  • xzlxt720
    Options
    I see your code ,it maybe the reason
    if(!alreadyOnline)
    {
    //Send information pertaining to the player to the client
    //Send information pertaining to the world to the client
    int[] targetActors = new int[1];
    targetActors[0] = originatingPlayer.actorNr;
    Peer.OpRaiseEvent((byte)PhotonEventCodes.EventCode.LoadSuccessful,null,true,1,targetActors);
    }
    else
    {
    SendForceDisconnect(originatingPlayer,"That player is already logged in.");
    }
  • Indeed; as I mentioned, I'm pretty sure that line of code (SendForceDisconnect...) is what is booting people off. I just don't see why it would be reaching that line of code; player one logs in, alreadyOnline should be false, and the LoadSuccessful event is raised. Player two logs in, LoadSuccessful is raised, and SendForceDisconnect is called on one, for whatever reason.

    Anyway, tested some more, referred to the logs, still couldn't hammer out the issue. As someone relatively new to Networking and this being the first project I've worked on utilizing Photon, could anyone explain actor numbers in greater detail? From my understanding, when a Peer connects to the server, it is assigned a unique actor number, so every one of them should be different, right?
  • chvetsov
    Options
    I repeat what Nicole said before. You need to add more debug logs. Right now you try to guess, this reason or this reason, or may be that ... who knows.
    If you have an idea why it does not work, just add debug logs. if after adding logs you still do not understand what is going on, add more logs

    Logging is the most efficient way to debug networking code.