Maintaining Photon Connection

I've been having lots of issues with maintaining connection to photon servers with every project I've used Photon with and frequently have problems when trying to join a room, even when there is no additional game data to be processed.

The project I'm working on uses an authentication system outside of Photon which supplies the user with the name of the room they should be creating/joining.

Here is a test project I put together to test a method of creating/joining a room immediately after connecting to the Photon master server.

[code2=csharp]using System.Collections.Generic;
using ExitGames.Client.Photon;
using UnityEngine;

public class PhotonConnectTest : MonoBehaviour
{
#region Photon Events

private void OnConnectedToPhoton()
{
_log.Insert(0, "<color=#00FF00>Connected to Photon</color>");
}

private void OnLeftRoom()
{
_log.Insert(0, "Left Room");
}

private void OnMasterClientSwitched(PhotonPlayer newMasterClient)
{
_log.Insert(0, "Master Client Switched " + newMasterClient.name);
}

private void OnPhotonCreateRoomFailed()
{
_log.Insert(0, "<color=#FFFF00>Room Creation Failed</color>");

// If creating the room failed, it's probably because the room is in the process of being created, start the cycle over again
Invoke("JoinRoom", 0.75f);
}

private void OnCreatedRoom()
{
_log.Insert(0, "<color=#00FF00>Created Room</color>");
}

private void OnDisconnectedFromPhoton()
{
_log.Insert(0, "<b>Disconnected from Photon</b>");

// Reconnect when disconnected (this causes the application to crash when closing while connected!)
if (!_started) return;
_log.Insert(0, "Reconnecting");
Connect();
}

private void OnConnectionFail(DisconnectCause cause)
{
_log.Insert(0, "<color=#FF0000>Connection Failed " + cause + "</color>");
}

private void OnFailedToConnectToPhoton(DisconnectCause cause)
{
_log.Insert(0, "<color=#FF0000>Failed to Connect to Photon</color>");
}

private void OnJoinedRoom()
{
_log.Insert(0, "<color=#00FF00>Joined Room</color>");
}

private void OnPhotonPlayerConnected(PhotonPlayer newPlayer)
{
_log.Insert(0, "Player Connected " + newPlayer.name);
}

private void OnPhotonPlayerDisconnected(PhotonPlayer otherPlayer)
{
_log.Insert(0, "Player Disconnected " + otherPlayer.name);
}

private void OnPhotonRandomJoinFailed()
{
_log.Insert(0, "<color=#99FF00>Failed to Join Room</color>");
CreateRoom();
}

private void OnConnectedToMaster()
{
_log.Insert(0, "<color=#33FF00>Connected to Master</color>");
JoinRoom();
}

private void OnPhotonMaxCccuReached()
{
_log.Insert(0, "Max CCU Reached");
}

#endregion

private readonly List<string> _log = new List<string>();
private string _roomName = "Room";
private Vector2 _scrollArea = Vector2.zero;

private bool _started;

private void Start()
{
_log.Insert(0, "Start");

PhotonNetwork.autoJoinLobby = false; // Don't need to join the lobby for random joining
PhotonNetwork.networkingPeer.TrafficStatsEnabled = true;
}

private void Connect()
{
_started = true;

PhotonNetwork.ConnectUsingSettings("1");
_log.Insert(0, "Connecting");
}

private void JoinRoom()
{
_log.Insert(0, "Joining Room: " + _roomName);

var roomInfo = new Hashtable {{"name", _roomName}};
PhotonNetwork.JoinRandomRoom(roomInfo, 0);
}

private void CreateRoom()
{
_log.Insert(0, "Creating Room: " + _roomName);

var roomInfo = new Hashtable {{"name", _roomName}};
PhotonNetwork.CreateRoom(_roomName, true, true, 20, roomInfo, new[] {"name"});
}

private void OnGUI()
{
if (!_started)
{
// Room setup
_roomName = GUILayout.TextField(_roomName, GUILayout.Width(200));
if (GUILayout.Button("Start"))
Connect();

return;
}

if (PhotonNetwork.room != null)
{
// Room info
GUILayout.BeginHorizontal();
GUILayout.Label(PhotonNetwork.room.name + " (" + _roomName + ")");

GUILayout.FlexibleSpace();

if (GUILayout.Button("Disconnect"))
{
_started = false;
PhotonNetwork.Disconnect();
}

GUILayout.EndHorizontal();
GUILayout.Label("Players in Room: " + PhotonNetwork.playerList.Length +
(PhotonNetwork.isMasterClient ? " (Master)" : ""));
}

// Photon stats
GUILayout.BeginVertical("Box");
GUILayout.Label("Status: " + PhotonNetwork.connectionStateDetailed);
GUILayout.EndVertical();
GUILayout.BeginVertical("Box");
GUILayout.Label("Game Level: " + PhotonNetwork.networkingPeer.TrafficStatsGameLevel);
GUILayout.Label("Time: " + (PhotonNetwork.networkingPeer.TrafficStatsElapsedMs/1000) + "s");
GUILayout.EndVertical();
GUILayout.BeginVertical("Box");
GUILayout.Label("Incoming");
GUILayout.Label(PhotonNetwork.networkingPeer.TrafficStatsIncoming.ToString());
GUILayout.EndVertical();
GUILayout.BeginVertical("Box");
GUILayout.Label("Outgoing");
GUILayout.Label(PhotonNetwork.networkingPeer.TrafficStatsOutgoing.ToString());
GUILayout.EndVertical();

// Log
_scrollArea = GUILayout.BeginScrollView(_scrollArea);

foreach (string message in _log)
GUILayout.Label(message);

GUILayout.EndScrollView();
}
}[/code2]

I have tried this with both Photon Cloud and with Photon Server and I have the same issue with each.

I build this into a windows standalone viewer and run multiple instances of it, when reaching 6 instances I will typically encounter problems, but sometimes less. One strange behaviour is when connecting with the later clients, the earlier clients get disconnected.

If anyone can tell me what I'm doing wrong, or any way I can improve this, it would be much appreciated.

Comments

  • I'm not sure that it's the same issue, but one issue my current project had a while back was if too many users launched the game connected at once, some of the got dropped or booted out. That whole problem went away when we added the game lobby system to it. So users would launch the game, not join a game right away, but either create or join a game based on what they pushed on that screen.

    A fix for it before we added the lobby was to just one by one, so first user connects, you wait until it fully connects, then launch the next, etc. That was a problem so we added the lobby, so I would try out the one by one thing and if that fixes the issue set up a lobby.

    I hope that helps, but if it wasn't the issue someone else will have to help more than I can :)
  • Please check out if the demos (e.g. the Boxes Demo) from PUN work or do produce the same issue. You could find out if it's a general issue or one with your code.
  • Thanks for the suggestions. I tried the box demo and everything seems to be working fine. So I'm not sure where I might be going wrong.

    We have had some internet connectivity issues recently which I am starting to think may be the cause of all of this. I tried the build I had previously done this morning and was able to connect 18 times with no issue. I tried this test a few times and have had no issue since.

    Although saying that, I have had similar issues in the past from numerous locations using different internet connections.
  • I hope it works out for you now.
    We are always looking into making the connection more stable but in almost all cases this affects the timeouts. So we can choose between less disconnects and longer times in which we don't timeout a user due to not being responsive. So it's not an easy pick.
    Let us know if you run into constant trouble again. And check the status tweet when you do: https://twitter.com/ExitGamesStatus