Disconnect Info
Overview
DisconnectInfo collects everything Fusion knows about why a peer was disconnected or a NetworkRunner was shut down. Several layers take part in a disconnect: the Fusion connection, the Fusion Plugin and the Photon Cloud connection. Each layer fills in its own part of the record, so most members are optional.
This was introduced respectively on Fusion SDK versions 2.0.14 and 2.1.4.
Where To Read It
| API | Description |
|---|---|
NetworkRunner.DisconnectInfo |
Record for the local peer. Null until a disconnect or a Shutdown happens. Read it inside OnDisconnectedFromServer, inside OnShutdown, or afterwards. A failed StartGame also leaves a record behind. The next StartGame resets it. Available on every peer. |
NetworkRunner.GetPlayerDisconnectInfo(PlayerRef) |
Record for a remote player that disconnected from this Server or Host. Read it from OnPlayerLeft. It stays available until the PlayerRef is reused by a new player or the runner shuts down. Returns null if the player has not disconnected, and always returns null on clients. Available on Server / Host. |
Members
| Member | Description |
|---|---|
ShutdownReason |
Why the runner shut down. It matches the value passed to OnShutdown, with one exception: if a failure was already recorded, a later plain Shutdown() (for example, one called from OnDisconnectedFromServer) keeps the failure reason. Stays ShutdownReason.Ok until the runner shuts down or a failure is recorded. Type ShutdownReason. |
NetDisconnectReason |
Reason reported by the Fusion connection, the same value passed to OnDisconnectedFromServer. Null when the Fusion connection was not involved, for example when only the Photon Cloud connection was lost. Type NetDisconnectReason?. |
Token |
Disconnect token. On a client, it is the token the Server or Host passed to NetworkRunner.Disconnect(PlayerRef, byte[]). On a player record, it is the token sent to or received from that player. Null when no token was exchanged. Type byte[]. |
PluginDisconnectReason |
Reason the Fusion Plugin sent when it removed this peer from the Room (see Fusion Plugin Reasons). Null when the Plugin was not involved, or when its message did not arrive before the Photon Cloud connection closed. Only set on NetworkRunner.DisconnectInfo. Type Fusion.Protocol.DisconnectReason?. |
CloudDisconnectCause |
Name of the Photon Realtime disconnect cause, for example "DisconnectByServerLogic" or "ClientTimeout". Null when the Photon Cloud connection was not involved. Only set on NetworkRunner.DisconnectInfo. Type string. |
Player |
The player the record belongs to. On a client's own record, it is the local player. On a record from GetPlayerDisconnectInfo, it is the remote player. PlayerRef.Invalid when the Fusion connection was not involved. Type PlayerRef. |
Message |
Human-readable detail: the message sent by the Fusion Plugin, or, if that message did not arrive, the Photon Cloud disconnect message. Only set on NetworkRunner.DisconnectInfo. Null when neither was received. Type string. |
DisconnectInfo.ToString() returns every member on one line, ready for logging.
Fusion Connection Reasons
DisconnectInfo.NetDisconnectReason holds the same value that OnDisconnectedFromServer receives:
NetDisconnectReason |
Meaning |
|---|---|
Timeout |
The connection timed out. |
SendWindowFull |
Data could not be delivered, because the send window filled up without acknowledgements. |
SequenceOutOfBounds |
A packet arrived with a sequence number outside of the accepted window. |
Requested |
This peer asked for the disconnect, for example a Host that called NetworkRunner.Disconnect(player). |
ByRemote |
The other side asked for the disconnect, for example a client kicked by its Host, or, seen from the Host, a client that left on its own. |
Unknown |
The reason is unknown. |
Timeout, SendWindowFull and SequenceOutOfBounds can be detected by either side, and the value does not say which side detected the problem.
Fusion Plugin Reasons
The Fusion Plugin removes peers from the Room in two situations:
- In Shared mode, when a player's Fusion connection to the Plugin ends.
- In Host mode, when the Host leaves and the Room is closed.
The Plugin sends a reason along. On the receiving peer, it is available as DisconnectInfo.PluginDisconnectReason, and the detail text is in DisconnectInfo.Message.
PluginDisconnectReason |
Meaning |
|---|---|
ConnectionTimeout |
The Fusion connection between the Plugin and the peer timed out. |
SendWindowFull |
The Plugin could not deliver data to the peer, because its send window filled up without acknowledgements. |
SequenceOutOfBounds |
A packet with a sequence number outside of the accepted window was detected. |
RequestedByClient |
The peer closed its Fusion connection to the Plugin on its own. |
ServerHasDisconnected |
The Server or Host left the Session and the Room was closed. In Host mode, Message includes how the Host left, for example whether it timed out. |
ServerLogic |
The Server explicitly disconnected the peer, for example after a protocol violation. |
All of these values reach OnShutdown as ShutdownReason.DisconnectedByPluginLogic, so existing code that checks for it keeps working. The specific reasons (ConnectionTimeout to ServerHasDisconnected) are only sent when every peer in the Session runs Fusion 2.0.14 (or newer) or Fusion 2.1.4 (or newer). Otherwise the Plugin sends ServerLogic, as earlier versions did.
The other DisconnectReason values (IncompatibleConfiguration, ServerAlreadyInRoom, Error and so on) describe failures to join or Plugin errors, and they keep their usual ShutdownReason.
Notes
- Every member can be null or unset, depending on which layers took part in the disconnect, so null-check before use.
NetworkRunner.DisconnectInfois still available after the runner has shut down, until the nextStartGame.- Records returned by
GetPlayerDisconnectInfoare cleared when the runner shuts down.
Examples
Showing why a client left the Session
C#
public void OnShutdown(NetworkRunner runner, ShutdownReason shutdownReason) {
var disconnectInfo = runner.DisconnectInfo;
Debug.Log($"Shutdown: {disconnectInfo}");
if (shutdownReason != ShutdownReason.DisconnectedByPluginLogic) {
return;
}
switch (disconnectInfo?.PluginDisconnectReason) {
case Fusion.Protocol.DisconnectReason.ConnectionTimeout:
case Fusion.Protocol.DisconnectReason.SendWindowFull:
Debug.Log("The connection to the Session was lost");
break;
case Fusion.Protocol.DisconnectReason.ServerHasDisconnected:
Debug.Log("The Host left the Session");
break;
default:
Debug.Log($"Removed from the Session: {disconnectInfo?.Message}");
break;
}
}
Telling a kicked player why
The Host passes a token to NetworkRunner.Disconnect. Only the first 128 bytes are sent.
C#
// Host
runner.Disconnect(player, System.Text.Encoding.UTF8.GetBytes("Kicked for inactivity"));
The client reads the token from DisconnectInfo:
C#
// Client
public void OnDisconnectedFromServer(NetworkRunner runner, NetDisconnectReason reason) {
var token = runner.DisconnectInfo?.Token;
if (reason == NetDisconnectReason.ByRemote && token != null) {
Debug.Log($"Disconnected by the Host: {System.Text.Encoding.UTF8.GetString(token)}");
}
}
Telling apart why a player left the Host
C#
public void OnPlayerLeft(NetworkRunner runner, PlayerRef player) {
switch (runner.GetPlayerDisconnectInfo(player)?.NetDisconnectReason) {
case NetDisconnectReason.Requested:
Debug.Log($"{player} was disconnected by this Host");
break;
case NetDisconnectReason.ByRemote:
Debug.Log($"{player} left the Session");
break;
case NetDisconnectReason.Timeout:
Debug.Log($"{player} timed out");
break;
}
}
Last updated on
Back to top