Photon Server By Examples 1 從頭構建一個Server


Photon Server據說好用但是能找到的資料太少,網上能找到為數不多數資料當中,針對Photon Server 3的版本講解還占了相當大的一部分,瞬間提高了門檻,讓初學者感覺不知道如何下手。情況如此,只好看官方的英文文檔,這幾篇文章主要結合示例項目代碼學習Photon Server的使用方法,翻譯、記錄、整理學習過程中看的文檔。

這一篇主要是從頭建立一個簡單的Server和Client。

建立Server

首先你需要:

  1. 下載并解壓Photon Server SDK。
  2. 使用Visual Studio創建一個類庫項目ChatServer,我用的是VS2015.
  3. 添加ExitGamesLibs.dll, Photon.SocketServer.dll和 PhotonHostRuntimeInterfaces.dll三個Dll,它們位于Photon Server根目錄的deploy\bin_Win64下面,注意系統版本。

好了,現在創建一個ChatServer類,繼承自ApplicationBase。

using Photon.SocketServer;
public class ChatServer : ApplicationBase
{
    protected override PeerBase CreatePeer(InitRequest initRequest)
    {
    }
    protected override void Setup()
    {
    }
    protected override void TearDown()
    {
    }
}

創建一個ChatPeer類繼承自Photon.SocketServer.ClientPeer。

using Photon.SocketServer;
using PhotonHostRuntimeInterfaces;
 
public class ChatPeer : ClientPeer
{
    public ChatPeer(InitRequest initRequest)
        : base(initRequest)
    {
    }
    protected override void OnDisconnect(DisconnectReason disconnectCode, string reasonDetail)
    {
    }
    protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
    {
    }
}

在ChatServer中的CreatePeer中返回一個ChatPeer的實例。

protected override PeerBase CreatePeer(InitRequest initRequest)
{
    return new ChatPeer(initRequest);
}

Photon Server實例啟動的時候會加載編譯好的ChatServer動態鏈接庫。因此我們需要在PhotonServer.config這個配置文件中加上這個程序的定義,添加下面的代碼段。

<ChatServer DisplayName="Chat Server">
<TCPListeners>
    <TCPListener
        IPAddress="0.0.0.0"
        Port="4530"
        OverrideApplication="ChatServer"
        >
    </TCPListener>
</TCPListeners>
<!-- Defines the Photon Runtime Assembly to use. -->
<Runtime
    Assembly="PhotonHostRuntime, Culture=neutral"
    Type="PhotonHostRuntime.PhotonDomainManager"
    UnhandledExceptionPolicy="Ignore">
</Runtime>
<!-- other elements -->
<Applications Default="ChatServer">
    <Application
        Name="ChatServer"
        BaseDirectory="ChatServer"
        Assembly="ChatServer"
        Type="ChatServer">
    </Application>
    <!-- any other applications -->
</Applications>
<!-- other elements -->
</ChatServer>

這個配置文件和前面的dll在同一個目錄下面。如果ChatServer類有命名空間的話,注意也要加上去。上述工程編譯好之后,二進制文件要放到deploy/ChatServer/bin文件夾下面。到此就做好了一個Server。啟動PhotonControll程序(需要管理員權限),在任務欄中會有Photon Server的圖標出現,右鍵單擊,選擇Chat Server/start as application,即可啟動Server程序。

建立Client

新創建一個控制臺工程,添加Photon3DotNet.dll到引用中,Client代碼如下:

using System;
using System.Collections.Generic;
using ExitGames.Client.Photon;
using System.Threading;
 
public class ChatClient : IPhotonPeerListener
{
    private bool connected;
    PhotonPeer peer;
 
    public static void Main()
    {
        var client = new ChatClient();
        client.peer = new PhotonPeer(client, ConnectionProtocol.Tcp);
        // connect
        client.DebugReturn(DebugLevel.INFO, "Connecting to server at 127.0.0.1:4530 using TCP");
        client.peer.Connect("127.0.0.1:4530", "ChatServer");
        // client needs a background thread to dispatch incoming messages and send outgoing messages
        client.Run();
        while (true)
        {
            if (!client.connected) { continue; }
            // read input
            string buffer = Console.ReadLine();
            // send to server
            var parameters = new Dictionary<byte, object> { { 1, buffer } };
            client.peer.OpCustom(1, parameters, true);
        }
    }
 
    private void UpdateLoop()
    {
        while (true)
        {
            peer.Service();
        }
    }
 
    public void Run()
    {
        Thread thread = new Thread(UpdateLoop); 
        thread.IsBackground = true;
        thread.Start();
    }
 
    #region IPhotonPeerListener
 
    public void DebugReturn(DebugLevel level, string message)
    {
        Console.WriteLine(string.Format("{0}: {1}", level, message));
    }
 
    public void OnEvent(EventData eventData)
    {
        DebugReturn(DebugLevel.INFO, eventData.ToStringFull());
        if (eventData.Code == 1)
        {
            DebugReturn(DebugLevel.INFO, string.Format("Chat Message: {0}", eventData.Parameters[1]));
        }
    }
 
    public void OnMessage(object messages)
    {
        throw new NotImplementedException();
    }
 
    public void OnOperationResponse(OperationResponse operationResponse)
    {
        DebugReturn(DebugLevel.INFO, operationResponse.ToStringFull());
    }
 
    public void OnStatusChanged(StatusCode statusCode)
    {
        if (statusCode == StatusCode.Connect)
        {
            connected = true;
        }
        switch (statusCode)
        {
            case StatusCode.Connect:
                DebugReturn(DebugLevel.INFO, "Connected");
                connected = true;
                break;
            default:
                DebugReturn(DebugLevel.ERROR, statusCode.ToString());
                break;
        }
    }
 
    #endregion
}

如果現在啟動server的話,client將能夠建立鏈接,并發送文本消息。不過現在還沒有服務端邏輯啊。Server端要確定收到了消息,并且能做出響應。可以在ChatPeer.OnOperationRequest函數中返回一個OperationResponse。

protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
    // send operation response (~ACK) back to peer
    var response = new OperationResponse(operationRequest.OperationCode);
    SendOperationResponse(response, sendParameters);
}

有了返回數據,客戶端現在就可以打印消息了。

下面我們要做的,是接收來自其他客戶端的聊天信息。我們使用發布/訂閱(publish/subscribe)模式來實現。

using Photon.SocketServer;
using PhotonHostRuntimeInterfaces;
using System;

public class ChatPeer : ClientPeer
{
  public ChatPeer(InitRequest request)
    : base(request)
{
    BroadcastMessage += OnBroadcastMessage;
}

private static event Action<ChatPeer, EventData, SendParameters> BroadcastMessage;

protected override void OnDisconnect(DisconnectReason disconnectCode, string reasonDetail)
{
    BroadcastMessage -= OnBroadcastMessage;
}

protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
    if (operationRequest.OperationCode == 1) // Chat Custom Operation Code = 1
    {
        // broadcast chat custom event to other peers
        var eventData = new EventData(1) { Parameters = operationRequest.Parameters }; // Chat Custom Event Code = 1
        BroadcastMessage(this, eventData, sendParameters);
        // send operation response (~ACK) back to peer
        var response = new OperationResponse(operationRequest.OperationCode);
        SendOperationResponse(response, sendParameters);
    }
}

private void OnBroadcastMessage(ChatPeer peer, EventData eventData, SendParameters sendParameters)
{
    if (peer != this) // do not send chat custom event to peer who called the chat custom operation 
    {
        SendEvent(eventData, sendParameters);
      }
  }
}

現在可以打開兩個客戶端,并且能夠相互收發消息了。不要忘記使用新的配置文件重新啟動Photon Server。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,915評論 18 139
  • 一:LoadRunner常見問題整理1.LR 腳本為空的解決方法:1.去掉ie設置中的第三方支持取消掉2.在系統屬...
    0100閱讀 4,238評論 0 11
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,765評論 18 399
  • 對于粉絲而言,愛豆的新歌永遠是第一時間就要去聽的。 上班期間躲在角落里帶上耳機。 上一個人剛熄滅了煙離開,伴著尼古...
    一謙閱讀 336評論 0 2
  • 禪師問:你覺得是一粒金子好,還是一堆爛泥好呢? 求道者答,當然是金子啊! 禪師笑曰,假如你是一顆種子呢? 其實,換...
    王志2017閱讀 212評論 0 0