This document is about: SERVER 4
SWITCH TO

호출 오퍼레이션

"기본 개념"에서 설명 하였듯이, 오퍼레이션은 Photon 어플리케이션에서 정의 된 원격 프로시져 호출입니다.
클라이언트 API 들은 LitePeer 클래스(또는 유사한 구조)가 포함되어 있으며 이 클래스는 서버의 오퍼레이션을 호출할 수 있는 메소드를 제공 합니다.
더 쉽게 작성하도록 하기 위하여 우리는 데모에서 Lite 어플리케이션을 사용합니다.

예를들어 LitePeer.OpJoinJoin 메소드를 감싸고 있습니다. 아래의 코드에서는 연결이 성립될 때 OpJoin 을 호출 할 것 입니다.

C#

    
        public void PeerStatusCallback(StatusCode returnCode)
        {
            // handle returnCodes for connect, disconnect and errors (non-operations)
            switch (returnCode)
            {
                case StatusCode.Connect:
                    this.DebugReturn("Connect(ed)");
                    this.peer.OpJoin(this.gameID);
                    break;
                //[...]
    

LitePeer 는 이 방식을 통해 모든 Lite 어플리케이션의 모든 부분을 다루고 있습니다.

Photon 으로 부터의 오퍼레이션 결과

오퍼레이션 마다, 서버의 어플리케이션은 결과를 전송할 수 있습니다. "GetHighscores" 오퍼레이션이 있고 점수 목록을 포함하고 있는 결과를 이용 할 수 있다고 가정하도록 하겠습니다.
RaiseEvent 와 같은 다른 RPC 들은 필요하지 않으면 안전하게 결과를 생략 할 수 있습니다.

오프레이션의 결과값을 얻는 것은 일반적으로 시간이 걸리는데, 네트워크 lag 가 있기 때문입니다.
이 때문에 모든 결과값들이 IPhotonPeerListener.OperationResult를 호출하여 비동기적으로 제공되는 이유 입니다.

플랫폼 마다 결과 콜백은 약간 차이가 있습니다. 다음의 코드는 C# 콜백 인터페이스로 게임에서 반드시 구현해야 합니다:

C#

    
    public interface IPhotonPeerListener
    {
        //[...]
        void OnOperationResponse(OperationResponse operationResponse);
    

OperationResult 콜백은 게임에서 peer.DispatchIncomingCommands 를 호출 할 때만 호출 됩니다.
이것은 올바른 스레드 컨텍스트에서 더 쉽게 콜백을 받을 수 있도록 해줍니다. 대부분의 경우 게임루프에서 매 몇 프레임마다 DispatchIncomingCommands 를 호출 하는 것만으로도 충분 합니다.

커스텀 오퍼레이션

커스텀 오퍼레이션은 어플리케이션 내에서 Exit Games(Lite, LoadBalancing 등.) 내에서 정의되지 않은 오퍼레이션들 입니다.
기본적으로 LitePeer 에서 다루지 않은 모든 오퍼레이션은 "커스텀" 입니다.
내부적으로 처리되어 있는 것을 살펴보면 Join 과 같이 커스텀 오퍼레이션이 아닌 것일 지라도 동일한 메소드를 사용한다는 것을 알 수 있을 것 입니다.
아래의 LitePeer Join 의 코드를 살펴 보세요:

C#

    
    public virtual bool OpJoin(string gameName, Hashtable gameProperties, Hashtable actorProperties, bool broadcastActorProperties)
    {
        if (this.DebugOut >= DebugLevel.ALL)
        {
            this.Listener.DebugReturn(DebugLevel.ALL, "OpJoin(" + gameName + ")");
        }

        Dictionary<byte, object> opParameters = new Dictionary<byte, object>();
        opParameters[(byte)LiteOpKey.GameId] = gameName;
        if (actorProperties != null)
        {
            opParameters[(byte)LiteOpKey.ActorProperties] = actorProperties;
        }

        if (gameProperties != null)
        {
            opParameters[(byte)LiteOpKey.GameProperties] = gameProperties;
        }

        if (broadcastActorProperties)
        {
            opParameters[(byte)LiteOpKey.Broadcast] = broadcastActorProperties;
        }

        return this.OpCustom((byte)LiteOpCode.Join, opParameters, true, 0, false);
    }
    

위에서 본것과 같이 OpJoin 은 내부적으로 OpCustom 을 이용하여 전송하고 있습니다.
이 메소드는 스트림라인을 둘러 싸는 것 입니다. 이것 또한 처리해 주셔야 합니다.

OpCustom 호출은 오퍼레이션 전송에 필요한 부분을 보여주고 있습니다:

  • OperationCode: 오퍼레이션을 식별하기위한 단일 바이트 (오버헤드를 최소화 하기 위해).
    예를 들어 (byte)LiteOpCode.Join 은 255 입니다.
  • Operation Parameters: 서버가 예측하고 있는 파라미터의 집합입니다.
    다시 한번 오버헤드를 최소화 하기 위해서 이름 대신 바이트를 사용하고 있습니다.
  • Reliability: OpCustom 의 세 번째 파라미터는 이 오퍼레이션이 반드시 서버에 도달 또는 손실 (unreliable) 될 수 있다는 것을 지정합니다.
    빠르게 대체 될수 있는 데이터는 비신뢰로 설정 할 수 있습니다.
    Join, Authentication 또는 유사한 것들은 신뢰로 전송하는 것이 더 좋습니다.
    (이 경우에 있어서 "true" 로 설정된 이유 입니다)
  • ChannelId: 는 시퀀스로 오퍼레이션이 순차적으로 위치하는 곳 입니다.
    대부분의 경우에 있어 0 으로 될 수 있습니다.
  • Encrypt: 선택적으로 클라이언트와 서버간의 데이터를 암호화 합니다.
    성능이 떨어지게 되므로 항상 필요하지는 않고 정말로 필요할 때만
    사용되어야 합니다. 여기에서는 false 입니다.

마지막 3개의 값들은 명백히 오퍼레이션의 일부가 아닙니다.
SendReliable, ChannelIdEncrypt 는 커뮤니케이션 설정으로
오퍼레이션에 따라 변경 될 수 있습니다.

오퍼레이션, 파라미터, 결과값들의 바이트 코드들은 서버측에서 정의 됩니다.
호출 하기 위해서는 클라이언트에서 상응되는 것을 사용해야 합니다.

오퍼레이션-호출 리턴 값

단순함을 위해서 우리는 리턴값이 있는 OpCustom (OpJoin 과 모든 다른 오퍼레이션들)을 무시하였습니다.
하지만 실용적인 효과를 가지고 있습니다:

현재 클라이언트의 상태에 따라서 오퍼레이션을 호출할 수 없을 수도 있습니다.
OpCustome 의 결과값은 오퍼레이션이 전송 될 수 있는지 또는 즉시 무시되는지를 알려 줍니다(클라이언트 측):

  • True: 오퍼레이션이 가능하고 서버로 보내질 것 입니다(SendOutgoingCommands() 를 통해). OpCustom 에 전달한 모든 값들은 직렬화 되고 상황에 따라 데이터를 변경할 수 있습니다.
  • False: 오퍼레이션을 전송 할 수 없습니다(예, 클라이언트가 연결되지 않았으므로).
    이상황이 발생한다면 클라이언트 라이브러리가 제공하는 디버그 힌트를 체크 해야 합니다(DebugReturn 참조).

새로운 오퍼레이션 정의 하기

대부분의 경우에 있어서 새로운 오퍼레이션의 정의는 서버측에서 수행 되기 때문에
구현과 사용하는 절차는 해당 컨텐스트에 설명되어 있습니다.
"오퍼레이션 추가하기" 문서를 읽어 보세요.

Back to top