Photon Server Configuration
This chapter explains how files and folders are organized for the Photon Server and how things are setup. Everything needed is in the "deploy" folder.
- Organization Of Server And Applications
- Configuration: PhotonServer.config
Organization Of Server And Applications
There are four versions of Photon in the folders: "bin_Win32" and "bin_Win64". We refer to these as binaries-folders.
Photon requires a separate folder next to the binaries-folder per application (e.g. "deploy\Loadbalancing" folder). The assemblies must be in a "bin" sub-folder (e.g. "deploy\Loadbalancing\bin").
The following folders in the Server SDK deploy folder are applications:
CounterPublisher, Loadbalancing, MmoDemo, Policy
Applications are setup in Photon's config file, as explained below.
The "bin_tools" folder currently contains useful tools:
- 7zip: Archive creation and extraction tool used to compress debug info files.
- baretail: Our favorite log viewer in the free edition. It is used by PhotonControl to view the latest logs.
- firewalltool: Tool to automatically set rules for Photon in Windows Firewall.
- perfmon: Contains a list of PerfMon counters used when you setup counter logging to a file. This is explained here.
- stardust.client: A command-line test client that can be used to get some load on a machine. This is shown in photon in 5 minutes
The main configuration file for Photon is the photonserver.config. An identical copy is located in each binaries-folder in the SDK. It is used to set up applications, listeners for IPs and performance specific values. It does not contain config values for the game logic.
The default values make sure Photon scales nicely on more cores but does not overwhelm a regular machine. In general performance tweaks are not needed.
The following settings are most commonly used. more options are described in the photon server config settings page.
The Application Node
The config file defines which applications Photon should load on startup. In the "Applications" node, several "Application" entries can be added.
<Applications Default="Master"> <Application Name="Master" BaseDirectory="LoadBalancing\Master" Assembly="Photon.LoadBalancing" Type="Photon.LoadBalancing.MasterServer.MasterApplication" ForceAutoRestart="true" WatchFiles="dll;config" ExcludeFiles="log4net.config" > </Application> <Application Name="Game" BaseDirectory="LoadBalancing\GameServer" Assembly="Photon.LoadBalancing" Type="Photon.LoadBalancing.GameServer.GameApplication" ForceAutoRestart="true" WatchFiles="dll;config" ExcludeFiles="log4net.config"> </Application> <!-- CounterPublisher Application --> <Application Name="CounterPublisher" BaseDirectory="CounterPublisher" Assembly="CounterPublisher" Type="Photon.CounterPublisher.Application" ForceAutoRestart="true" WatchFiles="dll;config" ExcludeFiles="log4net.config"> </Application> </Applications> </LoadBalancing>
Each application is assigned a name by which the clients reference it on connect.
The BaseDirectory defines the folder in which an application resides. It does not name the "\bin" folder but expects it by convention. The Assembly names the .dll of an application and "Type its "main" class (which derives from Photon.SocketServer.Application).
The setting ForceAutoRestart, when set to
true, tells Photon to restart the application and force all existing connections to disconnect.
If you use EnableAutoRestart however, when set to
true, Photon will start a shadow copy of the loaded application.
This allows developers to replace the files without locking issues, making development more convenient.
Photon will automatically start a new instance of an application after files are changed.
Clients connected to a previous shadow copy will stay in it.
New connects will use the new logic.
In both cases, WatchFiles and ExcludeFiles refines the list of files that trigger a restart. You can set a delay of the restart using RestartDelayMilliseconds setting, by default it's 1000 milliseconds.
For plugins development, we recommend running Photon Server right from the IDE using debug mode ("F5" in Visual Studio).
To load multiple applications, simply add more application nodes (with unique name). One of them can be made the default application by using its name ("Master" in the example). The default app is the fall-back for clients that try to connect to an unknown application.
Applications that are not setup in the PhotonServer.config won't be loaded and don't need to be deployed. When an application is in the config but the files are missing Photon won't start and name the issue in the logs.
UDPListeners And TCPListeners Nodes
These configure UDP and TCP endpoints on your machine respectively. You can use either (e.g. only UDP) or both.
The default IP 0.0.0.0 makes Photon listen on any locally available IP. By replacing the wild-card IP, Photon will open only specific IPs and ports. Multiple UDPListener and TCPListener nodes can be defined, opening several IP/port combinations.
Per UDPListener and TCPListener node, you can set up an OverrideApplication or DefaultApplication. Override means: any client that connects to this port will end up in the application named, no matter what the client connects to. Default is a fall-back, in case the application named by a client is not found.
<UDPListeners> <UDPListener IPAddress="0.0.0.0" Port="5055" OverrideApplication="Master"> </UDPListener> <UDPListener IPAddress="0.0.0.0" Port="5056" OverrideApplication="Game1"> </UDPListener> </UDPListeners>
Changing The Default UDP Ports
The default ports for UDP are:
- 5055 for the Master application
- 5056 for the Game Server application.
To change these ports, you need to do the following:
Open the Photon Server config in "deploy\bin_[Win_version]".
Edit the "Port" attribute of the
<UDPListeners> <UDPListener IPAddress="0.0.0.0" Port="5055" OverrideApplication="Master"> </UDPListener> <UDPListener IPAddress="0.0.0.0" Port="5056" OverrideApplication="Game"> </UDPListener> </UDPListeners>
In "deploy\Loadbalancing\GameServer\bin\Photon.LoadBalancing.dll.config", edit the "GamingUdpPort":
<setting name="GamingUdpPort" serializeAs="String"> <value>5056</value> </setting>
Change your client to connect to the new master server port. Restart Photon Server.
TCPSilverlightListeners And TCPFlashListeners Nodes
Could be removed but are needed when you create Silverlight or Flash games respectively. Both client-side plugins require a server to respond with a "policy file" (unless the website is on the same domain as Photon).
Two values in the instance node describe how the server times out unresponsive UDP clients:
MinimumTimeout and MaximumTimeout.
<Instance1 EnablePerformanceCounters = "true" DataSendingDelayMilliseconds="50" AckSendingDelayMilliseconds="50" MinimumTimeout="5000" MaximumTimeout="30000">
A peer connected with UDP has MinimumTimeout milliseconds to respond before it can be disconnected. The actual time until disconnect is determined dynamically per-peer based on the RTT history. Previously good RTTs will disconnect faster.
TCP connections have a separate InactivityTimeout setting in the nodes TCPListener and TCPPolicyListener (also in the PhotonServer.config). We set those to 5 seconds (5000ms). If no request arrives during this time, the connection will be timed out and closed. Clients will also regularly "ping" the server, to avoid this.
Keep in mind that a client independently monitors a connection and might time it out as well. Both sides should have similar timeouts, fitting your game.
Send Delay And Ack Delay
The attributes DataSendingDelayMilliseconds and AckSendingDelayMilliseconds represent a trade-off between performance and minimal response times. This delay directly adds some lag to reduce the traffic:
The wait allows the server to aggregate commands and send them in one package. The send delay is triggered when the server sends anything, the ack delay by incoming reliable data.
As you can see above, the default values are 50ms each. We found this to be a good value but it causes a ~50ms round-trip time, even if client and server run on the same machine.
Depending on your game, you should load test with different values.
A delay of 0 is a special case that skips usage of timers, so avoid low delays < 10.