Client side, Photon is built to give you as much control as possible. This makes sure it integrates well with your game loop.
It also requires some attention to avoid inexplicable disconnects, see also "Connections and Timeouts" in Basic Concepts. The following info should enable you to avoid them.
Disconnects by Client
- Client-side timeout (no/too late acks from server).
- Includes: case if server does not run
- Client socket exception (connection loss)
- Client connection fails on receive (buffer full, connection loss)
- Client connection fails on send (buffer full, connection loss)
- Note: Using localhost, C# raises exceptions even for UDP!
Disconnects by Server
- Server-side timeout (no/too late acks from client)
- Server send buffer full (too many messages)
- License or Subscription CCU limit hit
There are additional cases when client can't connect at all (bad address, no DNS available). In this context, those are not considered disconnects, because there never was a connection.
Keep calling Service
To include Photon in your client's game loop, you basically just have to call Service regularly. Regularly means between 10 to 50 times per second (depending on your game / network usage).
Service covers two tasks:
- Received events and data gets executed. This is done when you can handle the updates. As a sequence order is always kept intact, everything that the client receives is queued and ordered. Service calls DispatchIncomingCommands for this task.
- Outgoing data of your client is sent to the server. This includes acknowledgments (created in the background) which are important to keep connection to the server. Service internally calls SendOutgoingCommands to do this task. Controlling the frequency of SendOutgoingCommands calls controls the number of packages you use to send a client's produced data.
Profiling Service Calls
To detect if you called Service regularly, we added a statistics module to the client APIs.
If you encounter disconnects, check these values first:
The PhotonPeer.TrafficStatsGameLevel track how often you call DispatchIncomingCommands and SendOutgoingCommands when you turn the stats on (PhotonPeer.TrafficStatsEnabled = true). Check the values of LongestDeltaBetweenSending and LongestDeltaBetweenDispatching.
This feature is implemented in C# and Java based libraries currently. More platforms will get this soon. PUN has a GUI component for this: PhotonStatsGui.
Platform Specific Info
Unity and PUN
The Photon Unity Networking package implements the Service calls for you: PhotonHandler.Update calls Service in intervals.
However, Unity won't call Update while it's loading scenes (or maybe even any assets).
To keep the connection while loading scenes, you should set PhotonNetwork.IsMessageQueueRunning = false.
Pausing the message queue has two effects:
- A background Thread will be used to call SendOutgoingCommands while Update is not called. This keeps the connection alive, sending acknowledgements only but no events or operations (RPCs or sync updates). Incoming data is not executed by this Thread.
- All incoming updates are queued. Neither RPCs are called, nor are observed objects updated. While you change the level, this avoids calling RPCs in the previous one.
Photon Unity SDK
If you use the LoadBalancing API from our Photon Unity SDK, you probably do the Service calls in some MonoBehaviour Update method.
To make sure Photon's SendOutgoingCommands is called while you load scenes, implement a background thread. This thread should pause 100 or 200 ms between each loop, so it does not take away all performance.