4.x to 5.0 RC1 Upgrade Guide
This guide is for migrating from v4 to v5 versions equal or higher than v5.0 RC1 (not v5 BETA).
Overview of Major Changes
As on the Photon Cloud, v5 will now run a Name Server.
Clients should connect it to authenticate and get a Master Server address. This affects the authentication configuration.
The Photon Server requires a valid license to run.
CounterPublisher (App, Project and DLLs) was deprecated and removed from SDK.
Other than that, some configuration changes need to be reviewed.
License Updates and Upgrades
When upgrading to a new major version of the Photon SDK or when using an older SDK version with a newly purchased license file, you should make sure ahead of time before going into production, that your Photon SDK runs with that license.
The easiest way to do this is to put the license file in question into the Photon SDK folder you plan to use and start Photon via the Photon Control application.
You should then check the license information shown in the tray app and additionally check the logs for licensing errors.
Code changes
Here we list the possible changes needed to your custom classes that extend some commonly used types.
ApplicationBase
If you are extending ApplicationBase
class:
One of the constructors need to pass
IConfiguration
parameter to base contructor.
In order to do this you need to import NuGet package "Microsoft.Extensions.Configuration.Abstractions".
Then load the configuration (from XML or JSON or elsewhere) then pass it to base class constructor.
You can take a look at how we do it inMasterApplication
orGameApplication
orPhotonApp
classes.
Common pattern we use:C#
using Photon.SocketServer; using Microsoft.Extensions.Configuration; public class CustomPhotonApplication : ApplicationBase { public CustomPhotonApplication() : base(LoadConfiguration()) { } private static IConfiguration LoadConfiguration() {
(optional) New methods to override:
object DecryptAuthToken(InitRequest initRequest, byte[] authToken, int offset, int length, out Dictionary<byte, object> encryptionData, out string errorMsg)
void OnWebRTCChannelDestroyed(IPhotonWebRTCPeer peer, object userData, byte channelId)
ClientPeer
If you are extending ClientPeer
class:
void OnUnexpectedDataReceived(byte[] data, string debugMessage)
is gone and is replaced withvoid OnDeserializationError(byte[] data, RtsMessageType msgType, string debugMessage, short errorCode = -12, byte code = 0, Exception exception = null)
- First parameter of
OnDisconnected
has changed fromDisconnectReason
orint
:
before:void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
after:void OnDisconnect(int reasonCode, string reasonDetail)
- (optional) New methods to override:
string GetHistograms()
void OnEncryptionQueueOverload(EncryptionQueueFailureParams failureParams)
S2SPeerBase
Same as when extending ClientPeer
plus new extra optional method to override: void OnDisconnectMessage(DisconnectMessage message)
.
InboundS2SPeer
Same as when extending S2SPeerBase
.
OutboundS2SPeer
Same as when extending S2SPeerBase
plus new extra optional method to override void OnConnectionEstablished(InitV3Response initResponse)
.
PhotonServer.config Changes
We now support a new syntax for defining server application instances:
Instead of:XML
<Configuration> <InstanceName> </InstanceName> </Configuration>
Do:
XML
<Configuration> <Instance Name="InstanceName"> </Instance> </Configuration>
For the LoadBalancing instance, the default application is now NameServer and no longer Master as it used to be in v4.
Remove CounterPublisher application node from LoadBalancing instance.
Remove MMO instance.
Obsolete Settings
There are some settings removed in v5 and due to the newly introduced schema validation, the server will fail to start if these are still present.
Applications
- Shared Directory logic is old and not used.
Remove related setting:- SharedDirIsExeDir
Application
- Shared Directory logic is old and not used.
Remove related settings:- SharedDirIsExeDir
- SharedDirectory
- Automatic restarting of applications on change is now disabled.
Remove related settings:- RestartDelayMilliseconds
- WatchFiles
- ExcludeFiles
- EnableShadowCopy
- EnableAutoRestart
- ForceAutoRestart
- Resolver
- EnableOutboundENet
TCPListener
- Certificate setup has changed read more here.
Old certificate setup settings are gone:- StoreName
- UseMachineStore
- CertificateName
- DisconnectTimeout
- MaxQueuedBuffers
- MaxPendingWrites
- FlowControlNotificationStepSize
- PolicyApplication
HTTPListener
- Access-Control-Allow-Origin
Instance
- AttachConsole
- TCPUsePageAllocator
- UseStandardAllocator
- UseLockFreeAllocator
- UseTLSAllocator
- ENETUseLowContentionBufferAllocator
- ENETNumAllocators
- ENETUsePageAllocator
- ValidateCRCifPresent
IOPool / ENetIOPool / ENetThreadPool
"Priority" setting as been removed from all three pools.
Runtime
- OptimiseBroadcast removed
- UnhandledExceptionPolicy: Replace value "ReloadDomain" with "Ignore" or "TerminateProcess".
"ReloadDomain" is no longer supported.
HTTP WebSocket Listeners
WebSocketListeners have changed syntax.
Before (v4):
XML
<WebSocketListeners>
<WebSocketListener
IPAddress="0.0.0.0"
Port="9090"
DisableNagle="true"
InactivityTimeout="10000"
OverrideApplication="Master">
</WebSocketListener>
<WebSocketListener
IPAddress="0.0.0.0"
Port="9091"
DisableNagle="true"
InactivityTimeout="10000"
OverrideApplication="Game">
</WebSocketListener>
</WebSocketListeners>
After (v5):
XML
<HTTPListeners>
<HTTPListener
Name="*:[PORT]::Master"
IPAddress="0.0.0.0"
Port="9090"
DisableNagle="true"
InactivityTimeout="10000">
<Routing>
<Route
Url="/+"
OverrideApplication="Master"
PeerType="WebSocket"
Counters="false" />
<Route Url="/photon/m" Ping="true" Counters="false"/>
</Routing>
</HTTPListener>
<HTTPListener
Name="*:[PORT]::Game"
IPAddress="0.0.0.0"
Port="9091"
DisableNagle="true"
InactivityTimeout="10000"
AppDataInactivityTimeout="15000">
<Routing>
<Route
Url="/+"
OverrideApplication="Game"
PingEvery="2000"
PeerType="WebSocket"
Counters="false" />
<Route Url="/photon/g" Ping="true" Counters="false"/>
</Routing>
</HTTPListener>
<HTTPListener
Name="*:[PORT]::NameServer"
IPAddress="0.0.0.0"
Port="9093"
DisableNagle="true"
InactivityTimeout="10000"
AppDataInactivityTimeout="15000">
<Routing>
<Route
Url="/+"
OverrideApplication="NameServer"
PeerType="WebSocket"
Counters="false" />
<Route Url="/photon/n" Ping="true" Counters="false"/>
</Routing>
</HTTPListener>
</HTTPListeners>
Secure Listeners Setup
Since we have moved from Secure Channel (Schannel) to OpenSSL, certificate format and configuration for secure listeners have changed.
- Remove the obsolete attributes:
- StoreName
- UseMachineStore
- CertificateName
Replace with the new settings for certificates setup.
Read more on Certificate Setup.
LoadBalancing Configuration Changes
File Name Changes
First, the most noticebale difference is that now each server application has its own configuration file that has the following name format: "{application_name}.xml.config".
This is important especially for Master and GameServer applications that used to share the same file name and content by default: "Photon.LoadBalancing.dll.config".
The content of that file is now split into two files:
- "deploy\LoadBalancing\Master\bin\Master.xml.config"
- "deploy\LoadBalancing\GameServer\bin\GameServer.xml.config"
Here is the list of the configuration files:
Master
Before (v4):
"deploy\Loadbalancing\Master\bin\Photon.LoadBalancing.dll.config"
After (v5):
"deploy\LoadBalancing\Master\bin\Master.xml.config"
GameServer
Before (v4):
"deploy\Loadbalancing\GameServer\bin\Photon.LoadBalancing.dll.config"
After (v5):
"deploy\LoadBalancing\GameServer\bin\GameServer.xml.config"
Plugins
Game Server Plugins configuration is no longer part of the GameSever configuration file, it's now done in its own file "deploy\LoadBalancing\GameServer\bin\plugin.config".
In v4 it used to be inside "deploy\LoadBalancing\GameServer\bin\Photon.LoadBalancing.dll.config" so you need to move the plugins configuration from there.
Before (v4):
"deploy\Loadbalancing\GameServer\bin\Photon.LoadBalancing.dll.config"
After (v5):
"deploy\LoadBalancing\GameServer\bin\plugin.config"
Structure Change
The second important change is that configuration files have a new structure.
Old file structure:
XML
<?xml version="1.0"?>
<configuration>
<configSections>
<!-- sections defined here -->
</configSections>
<applicationSettings>
<!-- app settings -->
</applicationSettings>
<!-- other settings -->
<Photon>
<CounterPublisher>
</CounterPublisher>
</Photon>
<startup>
</startup>
</configuration>
New file structure:
XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<Photon>
<!-- all settings here -->
</Photon>
</configuration>
Notice the root <Photon>
element.
Some of the old configuration sections (XML elements) are no longer needed:
<configSections>
<applicationSettings>
<startup>
<CounterPublisher>
Some elements have been renamed.
<Photon.LoadBalancing.Common.CommonSettings>
is now<LoadBalacing>
<Photon.Common.Authentication.Settings>
is now<Authentication>
<Photon.LoadBalancing.MasterServer.MasterServerSettings>
is now<Master>
<Photon.LoadBalancing.GameServer.GameServerSettings>
is now<GameServer>
<WebRpcSettings>
is now<WebRpc>
<AuthSettings>
is now<CustomAuth>
Also now each setting node has a custom name matching the setting instead of the old generic format.
This applies to all elements except <WebRPC>
(previously <WebRpcSettings>
) and <CustomAuth>
(previously <AuthSettings
) which did not change.
Old setting node format:
XML
<setting name="SettingName" serializeAs="String">
<value>SettingValue</value>
</setting>
New setting node format:
XML
<SettingName>SettingValue</SettingName>
Here is a more detailed breakdown of the changes per file:
Master
<CustomAuth>
(previously <AuthSettings
) is no longer part of the MasterServer configuration and is instead done in NameServer ("deploy\NameServer\bin\NameServer.xml.config").
Old file structure:
XML
<?xml version="1.0"?>
<configuration>
<configSections>
<!-- sections defined here -->
</configSections>
<applicationSettings>
<Photon.LoadBalancing.Common.CommonSettings>
</Photon.LoadBalancing.Common.CommonSettings>
<Photon.Common.Authentication.Settings>
</Photon.Common.Authentication.Settings>
<Photon.LoadBalancing.MasterServer.MasterServerSettings>
</Photon.LoadBalancing.MasterServer.MasterServerSettings>
</applicationSettings>
<Photon>
<CounterPublisher>
</CounterPublisher>
</Photon>
<WebRpcSettings>
</WebRpcSettings>
<startup>
</startup>
</configuration>
New file structure:
XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<Photon>
<LoadBalancing>
</LoadBalancing>
<Authentication>
</Authentication>
<Master>
<S2S>
</S2S>
<GS>
</GS>
<Limits>
<Inbound>
</Inbound>
<Lobby>
</Lobby>
</Limits>
</Master>
<WebRpc>
<HttpQueueSetting>
</HttpQueueSettings>
</WebRpc>
<SocketServer>
<S2S>
</S2S>
</SocketServer>
</Photon>
</configuration>
GameServer
Old file structure:
XML
<?xml version="1.0"?>
<configuration>
<configSections>
<!-- sections defined here -->
</configSections>
<applicationSettings>
<Photon.LoadBalancing.Common.CommonSettings>
</Photon.LoadBalancing.Common.CommonSettings>
<Photon.Common.Authentication.Settings>
</Photon.Common.Authentication.Settings>
<Photon.LoadBalancing.MasterServer.GameServerSettings>
</Photon.LoadBalancing.MasterServer.GameServerSettings>
</applicationSettings>
<Photon>
<CounterPublisher>
</CounterPublisher>
</Photon>
<WebRpcSettings>
</WebRpcSettings>
<startup>
</startup>
</configuration>
New file structure:
XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<Photon>
<LoadBalancing>
</LoadBalancing>
<Authentication>
</Authentication>
<GameServer>
<S2S>
</S2S>
<Master>
</Master>
<Limits>
<Inbound>
<EventCache>
</EventCache>
<Properties>
</Properties>
<Operations>
</Operations>
</Inbound>
</Limits>
<HttpQueueSetting>
</HttpQueueSettings>
</GameServer>
<WebRpc>
<HttpQueueSetting>
</HttpQueueSettings>
</WebRpc>
<SocketServer>
<S2S>
</S2S>
</SocketServer>
</Photon>
</configuration>
Plugins
Add a <Configuration></Configuration>
enclosing wrapper element as follows:
XML
<Configuration>
<PluginSettings Enabled="True">
<Plugins>
<!-- custom plugin settings here -->
</Plugins>
</PluginSettings>
</Configuration>
HttpQueueSettings
HttpQueue is used for everything HTTP (outbound).
So it made sense to group the queue's related settings into one group.
This group of settings is used in GameServer, WebRPC and CustomAuth settings (as a subgroup).
Most of the settings were already available in v4 but now it's more organized (new structure), clean and consistent (naming).
HttpRequestTimeout
: How long (in milliseconds) the queue can wait for a HTTP response.LimitHttpResponseMaxSize
: Maximum size of HTTP response payload.MaxBackoffTime
: Backoff threshold when retrying to send a HTTP request.MaxConcurrentRequests
: Maximum concurrent HTTP requests allowed.MaxErrorRequests
: Maximum number of errors that can occur while processing queued requests.
If reached the HttpQueue will disconnect (clear all queued requests and reject incoming) and then resume after ReconnectInterval.MaxQueuedRequests
: Maximum number of requests that can be queued.MaxTimedOutRequests
: Maximum number of requests that timeout in the queue waiting to be processed.
If reached the HttpQueue will disconnect (clear all queued requests and reject incoming) and then resume after ReconnectInterval.QueueTimeout
: If a request stays in the HttpQueue for QueueTimeout milliseconds it will be removed automatically.ReconnectInterval
: How long (in milliseconds) the queue needs to wait before resuming process of HTTP requests.
Settings with same or similar names from GameServer, WebRPC or CustomAuth nodes need to be removed or moved under a <HttpQueueSettings>
element.
NameServer (NEW)
In v5 we added the NameServer application which was available in Photon Cloud only before.
Its configuration is done using two files:
one file for the actual application. Custom authentication is now done on the NameServer and not on the MasterServer anymore. So move any previously configured custom authentication settings from the MasterServer's configuration file (section used to be named
<AuthSettings>
) to the NameServer's configuration file (section renamed to<CustomAuth>
): "deploy\NameServer\bin\NameServer.xml.config".one file for the list of regions (MasterServer) to be associated with that NameServer. The file can be changed in 'NameServerConfig' setting in "deploy\NameServer\bin\NameServer.xml.config". Default is: "deploy\Nameserver.json"
'NameServer' is now the default application for the LoadBalancing instance in PhotonServer.config replacing 'Master' as it used to be in v4.
LoadBalancer and Workload Configuration Changes
Level Name Update
In v4 only 5 levels existed.
Those level names were 'Lowest', 'Low', 'Middle', 'High' and 'Highest'.
Now we use 'Level0', 'Level1', 'Level2', ..., 'Level9'.
'Lowest' is replaced with 'Level0'.
'Highest' is replaced with 'Level9'.
Workload Configuration Change
The GameServer setting "WorkloadConfigFile" sets the path for the LoadBalancer configuration file.
By default in v5 it's "deploy\Workload.1Gbps.config" (used to be "Workload.config").
Another example file is available in the SDK as well: "Workload.config".
Controller Setup Update
Old controller setup:
XML
<add Name="{ControllerName}" InitialInput="0" InitialLevel="Lowest">
<FeedbackLevels>
<add Level="Lowest" Value="{LowestValue}"/>
<add Level="Low" Value="{LowValue}"/>
<add Level="Normal" Value="{NormalValue}"/>
<add Level="High" Value="{HighValue}"/>
<add Level="Highest" Value="{HighestValue}"/>
</FeedbackLevels>
</add>
New controller setup:
XML
<Controller Name="{ContollerName}" InitialInput="0" InitialLevel="Lowest">
<FeedbackLevels>
<Level name="0" Level="Level0" Value="{Value0}" ValueDown="{ValueDown0}"/>
<Level name="1" Level="Level1" Value="{Value1}" ValueDown="{ValueDown1}"/>
<Level name="2" Level="Level2" Value="{Value2}" ValueDown="{ValueDown2}"/>
<Level name="3" Level="Level3" Value="{Value3}" ValueDown="{ValueDown3}"/>
<Level name="4" Level="Level4" Value="{Value4}" ValueDown="{ValueDown4}"/>
<Level name="5" Level="Level5" Value="{Value5}" ValueDown="{ValueDown5}"/>
<Level name="6" Level="Level6" Value="{Value6}" ValueDown="{ValueDown6}"/>
<Level name="7" Level="Level7" Value="{Value7}" ValueDown="{ValueDown7}"/>
<Level name="8" Level="Level8" Value="{Value8}" ValueDown="{ValueDown8}"/>
<Level name="9" Level="Level9" Value="{Value9}" ValueDown="{ValueDown9}"/>
</FeedbackLevels>
</Controller>
File Structure Update
Old structure:
XML
<?xml version="1.0" encoding="utf-8" ?>
<FeedbackControlSystem>
<FeedbackControllers>
<!-- one or more controllers setup -->
</FeedbackControllers>
</FeedbackControlSystem>
New structure (wrapper <Configuration></Configuration>
element/node added):
XML
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
<FeedbackControlSystem>
<FeedbackControllers>
<!-- one or more controllers setup -->
</FeedbackControllers>
</FeedbackControlSystem>
</Configuration>
LoadBalancer Configuration Change
The LoadBalancer configuration file is "deploy\LoadBalancer.config".
XML
<?xml version="1.0" encoding="utf-8" ?>
<LoadBalancer>
<LoadBalancerWeights>
<add Level="Lowest" Value="{LowestValue}"/>
<add Level="Low" Value="{LowValue}"/>
<add Level="Normal" Value="{NormalValue}"/>
<add Level="High" Value="{HighValue}"/>
<add Level="Highest" Value="{HighestValue}"/>
</LoadBalancerWeights>
</LoadBalancer>
New structure (wrapper <Configuration></Configuration>
element/node added):
XML
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
<LoadBalancer ReserveRatio="{ReserveRatio}" ValueUp="{ValueUp}">
<LoadBalancerWeights>
<Level name="0" Level="Level0" Value="{Value0}" />
<Level name="1" Level="Level1" Value="{Value1}"/>
<Level name="2" Level="Level2" Value="{Value2}"/>
<Level name="3" Level="Level3" Value="{Value3}"/>
<Level name="4" Level="Level4" Value="{Value4}"/>
<Level name="5" Level="Level5" Value="{Value5}"/>
<Level name="6" Level="Level6" Value="{Value6}"/>
<Level name="7" Level="Level7" Value="{Value7}"/>
<Level name="8" Level="Level8" Value="{Value8}"/>
<Level name="9" Level="Level9" Value="{Value9}"/>
</LoadBalancerWeights>
</LoadBalancer>
</Configuration>