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这个配置文件中加上这个程序的定义,添加下面的代码段。



    
    






    
    
    



这个配置文件和前面的dll在同一个目录下面。如果ChatServer类有命名空间的话,注意也要加上去。上述工程编译好之后,二进制文件要放到deploy/ChatServer/bin文件夹下面。到此就做好了一个Server。启动PhotonControll程序(需要管理员权限),在任务栏中会有Photon Server的图标出现,右键单击,选择Chat Server/start as application,即可启动Server程序。

Photon Server By Examples 1 从头构建一个Server_第1张图片

建立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 { { 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 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。

你可能感兴趣的:(Photon Server By Examples 1 从头构建一个Server)