Photon——An App From Scratch 一个应用程序从头开始

 

An App From Scratch 一个应用程序从头开始

     This tutorial will try to help you understand how to build an application from scratch.(aka “Blank Server Tutorial”)
     本教程将试图帮助您理解如何从头构建应用程序(又名空白服务器教程)
 

     Build a Simple Chat Server From the Scratch In 10 Minutes 

     10分钟从头开始构建一个简单的聊天服务器

     Hint: This tutorial is thought as a first step in understanding the basics of the main concepts in Photon Application and Peer. For most developers that at some point will use rooms we recommend to start with with an application that inherits from Lite.Application.
     提示:本教程是作为理解Photon应用和Peer中的主要概念的第一步。对于大多数开发人员来说,当使用房间时,我们建议应用程序继承自Lite应用程序。
  • Download and unzip the SDK
  • Create a new class library project ‘ChatServer’
  • Add references to ExitGamesLibs.dll, Photon.SocketServer.dll and PhotonHostRuntimeInterfaces.dll
  • Create a new class ‘ChatServer’ and inherit from ‘Photon.SocketServer.ApplicationBase’:
  • 下载并解压缩SDK
  • 创建一个新的类库项目”ChatServer”
  • 添加引用ExitGamesLibs.dll, Photon.SocketServer.dll and PhotonHostRuntimeInterfaces.dll
  • 创建一个新类的ChatServer和继承 Photon.SocketServer.ApplicationBase
using Photon.SocketServer;
 
public class ChatServer : ApplicationBase
{
    protected override PeerBase CreatePeer(InitRequest initRequest)
    {
    }
 
    protected override void Setup()
    {
    }
 
    protected override void TearDown()
    {
    }
}
  • Create a new class ‘ChatPeer’ and inherit from ‘Photon.SocketServer.PeerBase’:
  • 创建一个新的类ChatPeer并继承自Photon.SocketServer.PeerBase
using Photon.SocketServer;
using PhotonHostRuntimeInterfaces;
 
public class ChatPeer : PeerBase
{
    public ChatPeer(IRpcProtocol protocol, IPhotonPeer unmanagedPeer)
        : base(protocol, unmanagedPeer)
    {
    }
 
    protected override void OnDisconnect()
    {
    }
 
    protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
    {
    }
}
  • Return a new instance of ChatPeer at ChatServer.CreatePeer:
  • ChatServer.CreatePeer返回一个新的ChatPeer实例
protected override PeerBase CreatePeer(InitRequest initRequest)
{
    return new ChatPeer(initRequest.Protocol, initRequest.PhotonPeer);
}
  • The server configuration looks like this:
  • 服务器配置文件如下:
<Applications Default="ChatServer">
    <Application
        Name="ChatServer"
        BaseDirectory="ChatServer"
        Assembly="ChatServer"
        Type="ChatServer" />
</Applications>
 
     This config requires that the server binaries are located under ‘deploy/ChatServer/bin’ and that class ChatServer does not belong to a namespace.
     这种配置要求服务器二进制文件位于下 deploy/ChatServer/bin,这类ChatServer不属于一个名称空间。
  • Create a new console project for a chat client
  • Add reference to PhotoDotNet.dll to the new project
  • Client code:
  • 创建一个新的控制台项目作为聊天客户端
  • 添加引用PhotoDotNet.dll
  • 客户端代码:     
 
using System;
using System.Collections.Generic;
using System.Text;
 
using ExitGames.Client.Photon;
 
public class ChatClient : IPhotonPeerListener
{
    private bool connected;
 
    public static void Main()
    {
        var client = new ChatClient();
        var peer = new PhotonPeer(client, true);
             
        // connect
        client.connected = false;
        peer.Connect("127.0.0.1:4530", "ChatServer");
        while (!client.connected)
        {
            peer.Service();
        }
 
        var buffer = new StringBuilder();
        while (true)
        {
            peer.Service();
 
            // read input
            if (Console.KeyAvailable)
            {
                ConsoleKeyInfo key = Console.ReadKey();
                if (key.Key != ConsoleKey.Enter)
                {
                    // store input
                    buffer.Append(key.KeyChar);
                }
                else
                {
                    // send to server
                    var parameters = new Dictionary<byte, object> { { 1, buffer.ToString() } };
                    peer.OpCustom(1, parameters, true);
                    buffer.Length = 0;
                }
            }
        }
    }
 
    public void DebugReturn(DebugLevel level, string message)
    {
        Console.WriteLine(level + ": " + message);
    }
 
    public void OnEvent(EventData eventData)
    {
        Console.WriteLine("Event: " + eventData.Code);
        if (eventData.Code == 1)
        {  
            Console.WriteLine("Chat: " + eventData.Parameters[1]);
        }
    }
 
    public void OnOperationResponse(OperationResponse operationResponse)
    {
        Console.WriteLine("Response: " + operationResponse.OperationCode);
    }
 
    public void OnStatusChanged(StatusCode statusCode)
    {
        if (statusCode == StatusCode.Connect)
        {
            this.connected = true;
        }
        else
        {
            Console.WriteLine("Status: " + statusCode);
        }
    }
}
  • If we now start the server the client will be able to connect and to send text messages, but the server logic to process these text messages is still missing. To verify that the message was received we answer with an OperationResponse at ChatPeer.OnOperationRequest:
  • 如果我们开始这服务器,客户端将可能去连接并发送文本信息,但是服务器处理这些消息仍然会有丢失。为了验证这些信息是被接收到了,我们会在ChatPeer.OnOperationRequest响应一个OperationResponse:
protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
    var response = new OperationResponse(operationRequest.OperationCode);
    this.SendOperationResponse(response, sendParameters);
}
 
     The chat client should now print the event code and the chat message.
     这聊天客户端会打印事件代码和聊天信息
  • Next thing we want to do is to receive the chat messages on other clients. We implement a publish/subscribe pattern:
  • 接下来我们要做的就是在其他客户端接收聊天信息。我们实现了一个发布/订阅模式:
using System;
using Photon.SocketServer;
using PhotonHostRuntimeInterfaces;
 
public class ChatPeer : PeerBase
{
    private static readonly object syncRoot = new object();
 
    public ChatPeer(IRpcProtocol protocol, IPhotonPeer unmanagedPeer)
        : base(protocol, unmanagedPeer)
    {
        lock (syncRoot)
        {
            BroadcastMessage += this.OnBroadcastMessage;
        }
    }
 
    private static event Action<ChatPeer, EventData, SendParameters> BroadcastMessage;
 
    protected override void OnDisconnect()
    {
        lock (syncRoot)
        {
            BroadcastMessage -= this.OnBroadcastMessage;
        }
    }
 
    protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
    {
        var @event = new EventData(1) { Parameters = operationRequest.Parameters };
        lock (syncRoot)
        {
            BroadcastMessage(this, @event, sendParameters);
        }
 
        var response = new OperationResponse(operationRequest.OperationCode);
        this.SendOperationResponse(response, sendParameters);
    }
 
    private void OnBroadcastMessage(ChatPeer peer, EventData @event, SendParameters sendParameters)
    {
        if (peer != this)
        {
            this.SendEvent(@event, sendParameters);
        }
    }
}
 
     If you now start two clients they should be able to exchange messages.
     如果你现在开始运行2个客户端,他们可以交换信息。
posted @ 2013-05-15 13:45  M守护神  阅读(1295)  评论(0编辑  收藏  举报