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
首先你需要:
- 下載并解壓Photon Server SDK。
- 使用Visual Studio創(chuàng)建一個類庫項(xiàng)目ChatServer偶器,我用的是VS2015.
- 添加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蔗草。