server | v4 switch to v3  

App의 기초 부터

이 튜토리얼은 기초부터 어플리케이션을 어떻게 빌드 하는지 이해 할 수 있도록 도와 드립니다.

10분안에 간단한 채팅 서버 구축 하기.

노트: "5분안에 Photon 시작하기" 단계를 따라 했으며 로컬에 Photon 서버가 수행되고 있다고 가정합니다.

이 튜토리얼은 Photon 어플리케이션과 피어에 대한 주요 개념의 기초를 이해 하는 첫 단계 입니다.

  • Photon Server SDK 를 다운로드하고 압축을 해제 하세요.
  • Visual Studio를 사용하여 , 새로운 ChatServer class library project 를 생성 합니다.
  • 참조에 ExitGamesLibs.dll, Photon.SocketServer.dllPhotonHostRuntimeInterfaces.dll 을 추가 합니다.

이제 Photon.SocketServer.ApplicationBase 에서 상속을 받은 ChatServer 클래스를 생성 합니다:

    using Photon.SocketServer;

    public class ChatServer : ApplicationBase
    {
        protected override PeerBase CreatePeer(InitRequest initRequest)
        {
        }

        protected override void Setup()
        {
        }

        protected override void TearDown()
        {
        }
    }

Photon.SocketServer.ClientPeer 클래스에서 상속 받은 ChatPeer 클래스를 생성 합니다:

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

ChatServer 어셈블리는 Photon native 코어에 의해서 Default Photon 인스턴스 위에 로드될 것입니다. 따라서 서버 환경 설정 파일인 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>

이 환경설정에서는 서버 바이너리들이 deploy/ChatServer/bin 에 위치 해 있도록 설정 되어있고 ChatServer 클래스가 네임스페이스에 포함되어 있지 않습니다. 서버 환경설정에 대한 상세 정보는 개별 문서 페이지를 참고 하시기 바랍니다.

채팅 클라이언트를 위한 새로운 콘솔 프로젝트를 생성 하세요. 이 신규 프로젝트의 참조에 Photon3DotNet.dll 을 추가 하세요. 클라이언트 코드는 다음과 같습니다.

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
}

이제 서버를 시작하게 되면 클라이언트가 연결할 수 있으며 텍스트 메시지를 전송할 수 있습니다. 이러한 텍스트 메시지를 처리하는 서버 로직은 아직 없습니다. 메시지가 수신 되었는지를 검증 하기 위해서는 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 서버를 시작 하거나 새로운 환경설정이 있으면 재시작 하는 것을 잊지 마세요. 만약 문제가 발생하면 문서 페이지를 읽어 보세요.

기술문서 TOP으로 돌아가기