This document is about: SERVER 4
SWITCH TO

Server-To-Server Introduction

This is a tutorial for advanced developers. If you have just started to use Photon, you can safely skip this.

If you are developing a complex game, you probably want to distribute functionality between different servers. You can use Photon's Server-To-Server (S2S) features to implement the communication between your Photon servers.

Concept

S2S-communication in Photon is very similar to client-to-server-communication. One Photon instance initiates a connection (this is the "outbound" side of the connection) to the target Photon server (this is the "inbound" side of the connection). On each side, a peer is created and can be used to send operations / events over the S2S connection.

The outbound side

Let's assume you have an application "MyOutboundApplication", which inherits from ApplicationBase.

To initiate the S2S-connection, you need to call one of the OutboundS2SPeer.ConnectXXX methods. It is recommended to use TCP connections for S2S communication.

This code is needed to set up the S2S connection:

C#

    public class MyOutboundApplication : ApplicationBase
    {
        private MyOutboundPeer outboundPeer;
        protected override void Setup()
        {
            this.outboundPeer = new MyOutboundPeer(this);
            this.outboundPeer.ConnectTcp(new IPEndPoint(IPAddress.Parse("123.456.789.123"), 4520), "MyInboundApplication"); 
        }
    }

The above code establishes the S2S connection during Setup(). You can also do this later in your codebase. However, you should use only one connection between any two servers - keep the connection open and use that one connection to send all data through it.

To send data to your target server, you simply call the SendOperation method of that peer, like this:

C#

    public void SendMessageToMaster(string message)
    {
        var parameters = new Dictionary<byte, object>();
        parameters[0] = message;
        this.outboundPeer.SendOperationRequest(new OperationRequest { OperationCode = 1, Parameters = parameters }, new SendParameters());
    }

The implementation of the "OutboundPeer" class is quite simple as well. This is a minimal sample, add your own code as you see fit:

C#

    public class MyOutboundPeer : OutboundS2SPeer
    {
        public MyOutboundPeer(ApplicationBase application)
            : base(application)
        {
        }
        protected override void OnConnectionEstablished(object responseObject)
        {
        }
        protected override void OnConnectionFailed(int errorCode, string errorMessage)
        {
            // add some custom error handling here 
        }
        protected override void OnOperationResponse(OperationResponse operationResponse, SendParameters sendParameters)
        {
        }
        protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
        {
        }
    }

If the connection is established successfully, OnConnectionEstablished method will be triggered. Otherwise, the OnConnectionFailed() method is called. You might want to override that method and add some error handling, logging etc. there.

This is all that needs to be done on the "outbound" side of the S2S connection.

The "inbound" side

Now that the "outbound" side is done, we need to implement the "inbound" side of the S2S connection.

First, you need to create a peer object. To determine the incoming connection source ("client" or "server"), it is recommended to listen to different ports.

Let's assume that you have an application that inherits from ApplicationBase. Add this code:

C#

    protected override PeerBase CreatePeer(InitRequest initRequest)
    {
        if (initRequest.LocalPort == 4520)
        {
            // for S2S connections
            return new MyInboundPeer(initRequest); 
        }
    }

The MyInboundPeer is just a simple class that inherits of the PeerBase class:

C#

    public class MyInboundPeer : InboundS2SPeer
    {
        public MyInboundPeer(InitRequest initRequest)
            : base(initRequest)
        {
        }
        protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
        {
            // implement this to receive operation data
        }
        protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
        {
        }
    }

This is all that needs to be done on the "inbound" side of the S2S connection.

The configuration

If you have decided to use a separate port to listen for S2S connections on the inbound side, you need to define a new listener in the PhotonServer.config, like this:

XML

    <!-- DON'T EDIT THIS. TCP listener for S2S connections on MyOutbound application -->
    <TCPListener
        IPAddress="0.0.0.0"
        Port="4520">
    </TCPListener>
Back to top