Photon Server Configuration
The main configuration file for Photon is the PhotonServer.config. It is located in the binaries-folder of 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 do not overwhelm a regular machine. In general, performance tweaks are not needed.
The settings listed here are most commonly used. More options are described in the Photon Server Config Settings Page.
The Instance Node
Multiple instances are supported. Each instance has its separate node in the config file. An instance is a group of applications, listeners and other settings that should be used together when running the instance.
<Configuration> <Instance Name="CustomPhotonServerInstance" MaxMessageSize="512000" MaxQueuedDataPerPeer="512000" PerPeerMaxReliableDataInTransit="51200" PerPeerTransmitRateLimitKBSec="256" PerPeerTransmitRatePeriodMilliseconds="200" MinimumTimeout="5000" MaximumTimeout="30000" DisplayName="OwnCloudTM"> <!-- instance config here --> </Instance> </Configuration>
The instance node can have these attributes:
- Name: the name toe be used for the instance by Photon Socket Server.
- MaxMessageSize: maximum size allowed of messages sent by a single peer in bytes.
- MaxQueuedDataPerPeer: maximum buffer size capacity per peer in bytes.
- PerPeerMaxReliableDataInTransit: The maximum amount of reliable data that a peer can send and which the peer has not as yet received an ACK for. In bytes. Once this amount of data has been sent, all future reliable data will be queued.
- PerPeerTransmitRateLimitKBSec: The maximum amount of data (reliable AND unreliable) that can be sent in a second (in KB). This can be used to limit the amount of data that a peer can send. When the limit is reached further reliable data is queued and unreliable data is dropped.
- PerPeerTransmitRatePeriodMilliseconds: How often we check the transmission rate limit. By default, we check every 250ms (i.e. 4 times per second) and we scale the PerPeerTransmitRateLimitKBSec by 4 for each check. A smaller value makes the data flow more consistent while a larger value makes the flow more jerky but uses less server resources.
- MinimumTimeout (see "Timeout Settings")
- MaximumTimeout (see "Timeout Settings")
- DisplayName: the name to be displayed for the instance by PhotonControl.
- DataSendingDelayMilliseconds (see "Delay Settings")
- AckSendingDelayMilliseconds (see "Delay Settings")
- ProduceDumps: Switch to enable or disable creation of "dump files" in case of a crash. Dump files are essential to find issues in the Photon Core.
- DumpType (see "Photon Core Debugging")
- MaxDumpsToProduce (see "Photon Core Debugging")
- MaxDumpsToAttemptToProduce (see "Photon Core Debugging")
Two values in the instance node describe how the server times out unresponsive UDP clients: MinimumTimeout and MaximumTimeout.
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 (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.
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 sends 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 the client and the 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.
- LogFileLocation: log file location for the unmanaged Photon Socket Server. It can be either an absolute path or relative to "PhotonSocketServer.exe".
- LogFileName: the name of the unmanaged Photon Socket Server log file.
- LoggingEnabled: enable or disable unmanaged logging for this instance.
- LogUnimportantExceptions: whether or not to log some exceptions considered not important.
- ValidateSchema: enable or disable schema validation for this instance.
- SchemaValidationFailureIsFatal: whether or not schema validation failure results in server shutdown.
The Applications Node
The config file defines which applications Photon should load on startup. In the "Applications" node, several "Application" entries can be added.
To load multiple applications, simply add more application nodes (with unique names). One of them can be made the default application by using its name ("NameServer" in the example). The default app is the fall-back for clients that try to connect to an unknown application.
Applications that are not set up 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.
<!-- Defines which applications are loaded on start and which of them is used by default. Make sure the default application is defined. --> <!-- Application-folders must be located in the same folder as the bin_Win64 folders. The BaseDirectory must include a "bin" folder. --> <Applications Default="NameServer"> <Application Name="Master" BaseDirectory="LoadBalancing\Master" Assembly="Photon.LoadBalancing" Type="Photon.LoadBalancing.MasterServer.MasterApplication"> </Application> <Application Name="Game" BaseDirectory="LoadBalancing\GameServer" Assembly="Photon.LoadBalancing" Type="Photon.LoadBalancing.GameServer.GameApplication"> </Application> <Application Name="NameServer" BaseDirectory="NameServer" Assembly="Photon.NameServer" Type="Photon.NameServer.PhotonApp"> </Application> </Applications>
Each application has a name clients could use when connecting to it. The attributes supported by the application node:
- BaseDirectory: defines the folder in which an application resides. It does not name the "bin" folder but expects it by convention.
- Assembly: the ".dll" name of the application.
- Type: the "main" class of the application (which derives from Photon.SocketServer.ApplicationBase).
- PassUnknownAppsToDefaultApp: If true when an unknown application name is supplied the default application is used. If false then this is a fatal error which will terminate a connection. Default is false.
- StartTimeoutMilliseconds: Photon shuts down if the Application does not start in the configured amount of time. 0 = no timeout is applied.
- StopTimeoutMilliseconds: Photon shuts down if the Application does not stop in the configured amount of time. 0 = no timeout is applied.
These configure endpoints on your machine per protocol, IP and port. Multiple listeners types can be defined. Multiple listeners of the same type can be defined, opening several IP/port combinations.
These attributes are shared between most listeners.
- Name: optional name of the listener.
- IPAddress: The default IP 0.0.0.0 makes Photon listen on any locally available IP. Machines with multiple IPs should define the correct one here. By replacing the wild-card IP, Photon will open only the specific IP address.
- Port: port number to listen to.
- IPAddressIPv6: The IP Address to listen on, e.g. 2001:db8:a0b:12f0::1 or :: to listen on ALL interfaces.
- ListenBacklog: The size of the listen backlog queue. This affects the number of connections that can be established simultaneously; so, for example, if 151 clients attempt to connect at exactly the same time then the last one could be rejected. Note that each connection establishment attempt takes very little time and once the connection is established the connection is not affected by the limit. So you can set the value to 10 and still have 10,000 concurrent active connections as long as no more than 10 attempt to connect at exactly the same time.
- Disabled: Define if this listener is disabled.
- RecvBufferSize: The size of the buffer for the incoming data.
- SendBufferSize: The size of the buffer for the outgoing data.
TCP Listeners Settings
- FlowControlMaxQueuedBytes: The maximum amount of data that a peer can send. In bytes. Once this amount of data has been sent, all future data will be queued. This takes into consideration TCP Windows as the operating system's own buffer.
- DisableNagle: Determines if Nagle's algorithm is in use on the connection. If set to true then Nagle is disabled and outbound TCP data will be sent as soon as it reaches the TCP stack. If set to false then Nagle is in operation and the TCP stack will attempt to colasce outbound data into fewer datagrams. Setting this setting to true might improve the latency of your TCP connections a little, at the expense of there being more datagrams sent.
InactivityTimeout: how long before the server disconnects a non-responsive peer. "0" value means no timeout. In milliseconds.
LoggingEnabled: Define if this listener's logs are enabled.
Custom Connect Message
- CustomConnectMessagePrefix: Photon ignores the configured string if it sent as a prefix of a client's connect message.
- CustomConnectMessageSuffix: Photon ignores the configured string if it sent as a suffix of a client's connect message.
- CustomConnectMessageIsRequired: If set to true, a custom prefix / suffix is required on each Connect message.
Managed Application Settings
- OverrideApplication: any client that connects to this port will end up in the application named, no matter what the client connects to.
- DefaultApplication: is a fall-back, in case the application named by a client is not found.
- MaxMessageSize: Determines the default maximum number of bytes allowed for inbound and outbound messages.
- MaxInboundMessageSize: Determines the maximum number of bytes that a message might have which is received by the server through this Listener. If the message exceeds the MaxInboundMessageSize limit, the client will be disconnected from the server. Default is the configured value in MaxMessageSize.
- MaxOutboundMessageSize: Determines the maximum number of bytes that a message might have which is sent by the server through this Listener. If the message exceeds the MaxOutboundMessageSize limit, the client will be disconnected from the server. Default is the configured value in MaxMessageSize.
- AppDataInactivityTimeout: A timeout for the application (managed code) if it doesn't get any data as opposed to low level (native code) keep-alive pings.
In v5, WebSocketListeners are configured via HTTPListeners and specifiying
<HTTPListeners> <HTTPListener Name="MyListenerNameShowsUpInPerfMon" IPAddress="0.0.0.0" IPAddressIPv6="::" Port="80" OverrideApplication = "WebSocketEchoApp" InactivityTimeout="5000" DisableNagle="true" Secure = "true" PeerType="WebSocket" MaxUriLength="255" MaxHeaderLength="255" MaxHeaders="20" PermittedOrigins="photonengine.com, myawesome.game, etc." MaxInboundMessageSize="10000" MaxInboundMessageQueueSize="50000" MaxOutboundMessageSize="10000" MaxOutboundMessageQueueSize="50000" Ping="false" WebHook="false" NoCache="true"> <StandardHeaders> <StandardHeader Name="X-Blah" Value="X-BlahValue"/> <StandardHeader Name="X-Blah2" Value="X-Blah2Value"/> </StandardHeaders> <Routing> <Route Url="/"/> <!-- If present this is a wildcard match for ANY url not specified --> <Route Url="/photon/m" Ping="true" WebHook="true"/> <Route Url="/photon/g"/> <Route Url="/photon/g1" OverrideApplication="HttpApp1" PeerType="Websocket"/> <Route PermittedOrigins="*" Url="/photon/g2" InactivityTimeout="12000" MaxInboundMessageSize="10000" MaxInboundMessageQueueSize="50000" MaxOutboundMessageSize="10000" MaxOutboundMessageQueueSize="50000" OverrideApplication="HttpApp2"/> </Routing> </HTTPListener>
The idea is to configure a listener per application and optionally extra routes per endpoint and extra headers if needed. The configured routes could inherit from the base listener's settings or override them.
HttpListener node specific attribute:
- MaxUriLength: Maximum length of URI.
- MaxHeaderLength: Maximum length of a request header.
- MaxHeaders: Maximum number of request headers.
- MaxKeepAliveTime: Maximum duration allowed for keep alive connection.
- MaxKeepAliveRequests: Maximum requests allowed in the same keep alive connection.
- CloseDelayMilliseconds: Delay after which the connection will be closed.
Route node specific attributes:
- SubProtocols: only for WebSockets peer type.
- PingEvery: How often should this endpoint be pinged.
Only for WebSockets peer type.
Requires "Ping" to be
Attributes shared between HttpListener and Route nodes:
- Name: Name of the listener or route.
- PermittedOrigins: Whitelisted domains. Used to be called "Access-Control-Allow-Origin" in v5 BETA and sets HTTP response header of the same name (CORS).
falseif this endpoint should be pinged or not.
falseif this endpoint should be a WebHook.
- Url: URL for this endpoint.
Note: By default, route level Windows Performance counters are not created for HTTP listeners with a single route.
Defines the Photon Runtime Assembly to use.
<Runtime Assembly="PhotonHostRuntime, Culture=neutral" Type="PhotonHostRuntime.PhotonDomainManager" UnhandledExceptionPolicy="TerminateProcess"> </Runtime>
- UnhandledExceptionPolicy (see "Exception Handling")
To simplify configuration of paths, we provide a set of macros for the most important folders:
[EXE]: the folder containing the server executable "PhotonSocketServer.exe".
[CONFIG]: the folder containing the configuration file used by the server.
[DEPLOY]: the parent folder of
[CERTS]: the default "CertificatePath" value:
You can use the macros to form relative paths. The macros are logged on server startup in the unmanaged PhotonSocketServer log file:
22572: 16:13:36.098 - Config File: D:\ExitGames\SDKs\Server\Photon-OnPremises-Server-Classic-SDK_v5-0-12-24441-RC1\deploy\bin_Win64\PhotonServer.config 22572: 16:13:36.098 - Config|INFO| Adding config path macro: "[CONFIG]" - "D:\ExitGames\SDKs\Server\Photon-OnPremises-Server-Classic-SDK_v5-0-12-24441-RC1\deploy\bin_Win64" 22572: 16:13:36.098 - Config|INFO| Adding config path macro: "[DEPLOY]" - "[CONFIG]\.." 22572: 16:13:36.098 - Config|INFO| Adding config path macro: "[EXE]" - "D:\ExitGames\SDKs\Server\Photon-OnPremises-Server-Classic-SDK_v5-0-12-24441-RC1\deploy\bin_Win64" 22572: 16:13:36.098 - Config|INFO| Adding config path macro: "[CERTS]" - "[EXE]\certs"
Macros can be overridden with explicit paths via PhotonServer Instance settings:
Route level counter names can include the following macros:
[ADDRESS]: IP address e.g. 192.168.0.1.
[PORT]: Port number e.g. 8080.
[FULL_ADDRESS]: IP address and port: 192.168.0.1:8080.
[ENDPOINT]: name from endpoint.
[PARENT]: name from endpoint or ParentCounters="".
Managed SocketServer Settings
You can configure some settings related to the PhotonSocketServer from the application level.
This can be done any server application by adding an optional
<SocketServer> node/element to the application's respective configuration file as follows (the example includes the default values for each setting):
<?xml version="1.0" encoding="utf-8" ?> <configuration> <Photon> <SocketServer SecurityProtocol="Tls12|Tls13" Protocols="GpBinaryV16,GpBinaryV18,Json" LogGuardOn="true"> <Limits MessageRate="5000" MessageDataRate="2147483647" MaxMessageSize="512000" OnlyLogViolations="false"/> <S2S RpcProtocol="GpBinaryV18" UseInitV3="false"/> </SocketServer> </Photon> </configuration>
SecurityProtocol: Defines which TLS version the server should use. The default value is the recommended and more secure one as TLS1.2 and TLS1.3 are the standards now. Change this only if necessary. Possible values:
Ssl3|Tls|Tls11|Tls12|Tls13. This sets .NET's
Protocols: Defines which data serialization protocols could be used by this server application.
MessageRate: The maximum number allowed of incoming messages per peer per second. Default is 5000.
MessageDataRate: The maximum size allowed of buffered incoming data per peer per second. Default is 2147483647 (
MaxMessageSize: The maximum size allowed for incoming messages. Default is 512000.
LogGuardOn: Enable or disable guard against logging spam.
OnlyLogViolations: Defines which measure to take when limits are violated: log violation or disconnect peer.
RpcProtocol: Data serialization protocol used for server-to-server communication.
UseInitV3: Whether or not to use InitRequest version 3 for server-to-server communication.