Photon Server By Examples 1 從頭構(gòu)建一個Server


Photon Server據(jù)說好用但是能找到的資料太少聂示,網(wǎng)上能找到為數(shù)不多數(shù)資料當(dāng)中耿战,針對Photon Server 3的版本講解還占了相當(dāng)大的一部分琉用,瞬間提高了門檻,讓初學(xué)者感覺不知道如何下手俊啼。情況如此肺缕,只好看官方的英文文檔,這幾篇文章主要結(jié)合示例項(xiàng)目代碼學(xué)習(xí)Photon Server的使用方法授帕,翻譯同木、記錄、整理學(xué)習(xí)過程中看的文檔豪墅。

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

建立Server

首先你需要:

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

好了颊郎,現(xiàn)在創(chuàng)建一個ChatServer類,繼承自ApplicationBase霎苗。

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

創(chuàng)建一個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的實(shí)例。

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

Photon Server實(shí)例啟動的時候會加載編譯好的ChatServer動態(tài)鏈接庫唁盏。因此我們需要在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類有命名空間的話昆淡,注意也要加上去。上述工程編譯好之后刽严,二進(jìn)制文件要放到deploy/ChatServer/bin文件夾下面昂灵。到此就做好了一個Server。啟動PhotonControll程序(需要管理員權(quán)限)舞萄,在任務(wù)欄中會有Photon Server的圖標(biāo)出現(xiàn)眨补,右鍵單擊,選擇Chat Server/start as application倒脓,即可啟動Server程序撑螺。

建立Client

新創(chuàng)建一個控制臺工程,添加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
}

如果現(xiàn)在啟動server的話实蓬,client將能夠建立鏈接,并發(fā)送文本消息吊履。不過現(xiàn)在還沒有服務(wù)端邏輯啊安皱。Server端要確定收到了消息,并且能做出響應(yīng)艇炎∽靡粒可以在ChatPeer.OnOperationRequest函數(shù)中返回一個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);
}

有了返回?cái)?shù)據(jù)缀踪,客戶端現(xiàn)在就可以打印消息了居砖。

下面我們要做的,是接收來自其他客戶端的聊天信息驴娃。我們使用發(fā)布/訂閱(publish/subscribe)模式來實(shí)現(xiàn)奏候。

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);
      }
  }
}

現(xiàn)在可以打開兩個客戶端,并且能夠相互收發(fā)消息了唇敞。不要忘記使用新的配置文件重新啟動Photon Server蔗草。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末咒彤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子咒精,更是在濱河造成了極大的恐慌镶柱,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件模叙,死亡現(xiàn)場離奇詭異歇拆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)范咨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進(jìn)店門故觅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人渠啊,你說我怎么就攤上這事输吏。” “怎么了昭抒?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵评也,是天一觀的道長。 經(jīng)常有香客問我灭返,道長盗迟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任熙含,我火速辦了婚禮罚缕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘怎静。我一直安慰自己邮弹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布蚓聘。 她就那樣靜靜地躺著腌乡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪夜牡。 梳的紋絲不亂的頭發(fā)上与纽,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天,我揣著相機(jī)與錄音塘装,去河邊找鬼急迂。 笑死,一個胖子當(dāng)著我的面吹牛蹦肴,可吹牛的內(nèi)容都是我干的僚碎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼阴幌,長吁一口氣:“原來是場噩夢啊……” “哼勺阐!你這毒婦竟也來了卷中?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤皆看,失蹤者是張志新(化名)和其女友劉穎仓坞,沒想到半個月后背零,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腰吟,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年徙瓶,在試婚紗的時候發(fā)現(xiàn)自己被綠了毛雇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡侦镇,死狀恐怖灵疮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情壳繁,我是刑警寧澤震捣,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站闹炉,受9級特大地震影響蒿赢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜渣触,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一羡棵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嗅钻,春花似錦皂冰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至柳弄,卻和暖如春舶胀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背语御。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工峻贮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人应闯。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓纤控,卻偏偏與公主長得像,于是被迫代替她去往敵國和親碉纺。 傳聞我的和親對象是個殘疾皇子船万,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理刻撒,服務(wù)發(fā)現(xiàn),斷路器耿导,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • 一:LoadRunner常見問題整理1.LR 腳本為空的解決方法:1.去掉ie設(shè)置中的第三方支持取消掉2.在系統(tǒng)屬...
    0100閱讀 4,118評論 0 11
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法声怔,類相關(guān)的語法,內(nèi)部類的語法舱呻,繼承相關(guān)的語法醋火,異常的語法,線程的語...
    子非魚_t_閱讀 31,625評論 18 399
  • 對于粉絲而言,愛豆的新歌永遠(yuǎn)是第一時間就要去聽的茬高。 上班期間躲在角落里帶上耳機(jī)兆旬。 上一個人剛熄滅了煙離開,伴著尼古...
    一謙閱讀 315評論 0 2
  • 禪師問:你覺得是一粒金子好,還是一堆爛泥好呢熏瞄? 求道者答脚祟,當(dāng)然是金子啊巴刻! 禪師笑曰愚铡,假如你是一顆種子呢? 其實(shí)胡陪,換...
    王志2017閱讀 202評論 0 0