in MRTK Tutorials/Assets/Photon/PhotonRealtime/Code/LoadBalancingClient.cs [2935:3158]
public virtual void OnStatusChanged(StatusCode statusCode)
{
switch (statusCode)
{
case StatusCode.Connect:
if (this.State == ClientState.ConnectingToNameServer)
{
if (this.LoadBalancingPeer.DebugOut >= DebugLevel.ALL)
{
this.DebugReturn(DebugLevel.ALL, "Connected to nameserver.");
}
this.Server = ServerConnection.NameServer;
if (this.AuthValues != null)
{
this.AuthValues.Token = null; // when connecting to NameServer, invalidate the secret (only)
}
}
if (this.State == ClientState.ConnectingToGameServer)
{
if (this.LoadBalancingPeer.DebugOut >= DebugLevel.ALL)
{
this.DebugReturn(DebugLevel.ALL, "Connected to gameserver.");
}
this.Server = ServerConnection.GameServer;
}
if (this.State == ClientState.ConnectingToMasterServer)
{
if (this.LoadBalancingPeer.DebugOut >= DebugLevel.ALL)
{
this.DebugReturn(DebugLevel.ALL, "Connected to masterserver.");
}
this.Server = ServerConnection.MasterServer;
this.ConnectionCallbackTargets.OnConnected(); // if initial connect
}
if (this.LoadBalancingPeer.TransportProtocol != ConnectionProtocol.WebSocketSecure)
{
if (this.Server == ServerConnection.NameServer || this.AuthMode == AuthModeOption.Auth)
{
this.LoadBalancingPeer.EstablishEncryption();
}
}
else
{
goto case StatusCode.EncryptionEstablished;
}
break;
case StatusCode.EncryptionEstablished:
if (this.Server == ServerConnection.NameServer)
{
this.State = ClientState.ConnectedToNameServer;
// if there is no specific region to connect to, get available regions from the Name Server. the result triggers next actions in workflow
if (string.IsNullOrEmpty(this.CloudRegion))
{
this.OpGetRegions();
break;
}
}
else
{
// auth AuthOnce, no explicit authentication is needed on Master Server and Game Server. this is done via token, so: break
if (this.AuthMode == AuthModeOption.AuthOnce || this.AuthMode == AuthModeOption.AuthOnceWss)
{
break;
}
}
// authenticate in all other cases (using the CloudRegion, if available)
bool authenticating = this.CallAuthenticate();
if (authenticating)
{
this.State = ClientState.Authenticating;
}
else
{
this.DebugReturn(DebugLevel.ERROR, "OpAuthenticate failed. Check log output and AuthValues. State: " + this.State);
}
break;
case StatusCode.Disconnect:
// disconnect due to connection exception is handled below (don't connect to GS or master in that case)
this.friendListRequested = null;
bool wasInRoom = this.CurrentRoom != null;
this.CurrentRoom = null; // players get cleaned up inside this, too, except LocalPlayer (which we keep)
this.ChangeLocalID(-1); // depends on this.CurrentRoom, so it must be called after updating that
if (this.Server == ServerConnection.GameServer && wasInRoom)
{
this.MatchMakingCallbackTargets.OnLeftRoom();
}
if (this.ExpectedProtocol != null && this.LoadBalancingPeer.TransportProtocol != this.ExpectedProtocol)
{
this.DebugReturn(DebugLevel.INFO, string.Format("On disconnect switches TransportProtocol to ExpectedProtocol: {0}.", this.ExpectedProtocol));
this.LoadBalancingPeer.TransportProtocol = (ConnectionProtocol)this.ExpectedProtocol;
this.ExpectedProtocol = null;
}
switch (this.State)
{
case ClientState.ConnectWithFallbackProtocol:
this.EnableProtocolFallback = false; // the client does a fallback only one time
this.LoadBalancingPeer.TransportProtocol = (this.LoadBalancingPeer.TransportProtocol == ConnectionProtocol.Tcp) ? ConnectionProtocol.Udp : ConnectionProtocol.Tcp;
this.NameServerPortInAppSettings = 0; // this does not affect the ServerSettings file, just a variable at runtime
this.ServerPortOverrides = new PhotonPortDefinition(); // use default ports for the fallback
if (!this.LoadBalancingPeer.Connect(this.NameServerAddress, this.ProxyServerAddress, this.AppId, this.TokenForInit))
{
return;
}
this.State = ClientState.ConnectingToNameServer;
break;
case ClientState.PeerCreated:
case ClientState.Disconnecting:
if (this.AuthValues != null)
{
this.AuthValues.Token = null; // when leaving the server, invalidate the secret (but not the auth values)
}
this.State = ClientState.Disconnected;
this.ConnectionCallbackTargets.OnDisconnected(this.DisconnectedCause);
break;
case ClientState.DisconnectingFromGameServer:
case ClientState.DisconnectingFromNameServer:
this.ConnectToMasterServer(); // this gets the client back to the Master Server
break;
case ClientState.DisconnectingFromMasterServer:
this.Connect(this.GameServerAddress, this.ProxyServerAddress, ServerConnection.GameServer); // this connects the client with the Game Server (when joining/creating a room)
break;
case ClientState.Disconnected:
// this client is already Disconnected, so no further action is needed.
// this.DebugReturn(DebugLevel.INFO, "LBC.OnStatusChanged(Disconnect) this.State: " + this.State + ". Server: " + this.Server);
break;
default:
string stacktrace = "";
#if DEBUG && !NETFX_CORE
stacktrace = new System.Diagnostics.StackTrace(true).ToString();
#endif
this.DebugReturn(DebugLevel.WARNING, "Got a unexpected Disconnect in LoadBalancingClient State: " + this.State + ". Server: " + this.Server + " Trace: " + stacktrace);
if (this.AuthValues != null)
{
this.AuthValues.Token = null; // when leaving the server, invalidate the secret (but not the auth values)
}
this.State = ClientState.Disconnected;
this.ConnectionCallbackTargets.OnDisconnected(this.DisconnectedCause);
break;
}
break;
case StatusCode.DisconnectByServerUserLimit:
this.DebugReturn(DebugLevel.ERROR, "This connection was rejected due to the apps CCU limit.");
this.DisconnectedCause = DisconnectCause.MaxCcuReached;
this.State = ClientState.Disconnecting;
break;
case StatusCode.DnsExceptionOnConnect:
this.DisconnectedCause = DisconnectCause.DnsExceptionOnConnect;
this.State = ClientState.Disconnecting;
break;
case StatusCode.ServerAddressInvalid:
this.DisconnectedCause = DisconnectCause.ServerAddressInvalid;
this.State = ClientState.Disconnecting;
break;
case StatusCode.ExceptionOnConnect:
case StatusCode.SecurityExceptionOnConnect:
case StatusCode.EncryptionFailedToEstablish:
this.DisconnectedCause = DisconnectCause.ExceptionOnConnect;
// if enabled, the client can attempt to connect with another networking-protocol to check if that connects
if (this.EnableProtocolFallback && this.State == ClientState.ConnectingToNameServer)
{
this.State = ClientState.ConnectWithFallbackProtocol;
}
else
{
this.State = ClientState.Disconnecting;
}
break;
case StatusCode.Exception:
case StatusCode.ExceptionOnReceive:
case StatusCode.SendError:
this.DisconnectedCause = DisconnectCause.Exception;
this.State = ClientState.Disconnecting;
break;
case StatusCode.DisconnectByServerTimeout:
this.DisconnectedCause = DisconnectCause.ServerTimeout;
this.State = ClientState.Disconnecting;
break;
case StatusCode.DisconnectByServerLogic:
this.DisconnectedCause = DisconnectCause.DisconnectByServerLogic;
this.State = ClientState.Disconnecting;
break;
case StatusCode.DisconnectByServerReasonUnknown:
this.DisconnectedCause = DisconnectCause.DisconnectByServerReasonUnknown;
this.State = ClientState.Disconnecting;
break;
case StatusCode.TimeoutDisconnect:
this.DisconnectedCause = DisconnectCause.ClientTimeout;
// if enabled, the client can attempt to connect with another networking-protocol to check if that connects
if (this.EnableProtocolFallback && this.State == ClientState.ConnectingToNameServer)
{
this.State = ClientState.ConnectWithFallbackProtocol;
}
else
{
this.State = ClientState.Disconnecting;
}
break;
}
}