오브젝트 표시(Object Visibility)
Local Discovery

네트워크 메시지

명령과 RPC 호출의 고레벨 기능 이외에도, raw 네트워크 메시지도 보낼 수 있습니다.

MessageBase라는 클래스는 직렬화 가능한 네트워크 메시지 클래스를 만들기 위해 확장할 수 있습니다. 이 클래스는 읽기와 쓰기의 오브젝트로서 대응하는 직렬화 함수와 역직렬화 함수를 가지고 있습니다. 개발자는 이 함수를 직접 구현할 수도 있으며, 네트워킹 시스템에 따라 자동으로 생성하는 코드-생성 구현을 사용할 수도 있습니다. 기반 클래스는 다음과 같습니다:

public abstract class MessageBase
{
    // De-serialize the contents of the reader into this message
    public virtual void Deserialize(NetworkReader reader) {}

    // Serialize the contents of this message into the writer
    public virtual void Serialize(NetworkWriter writer) {}
}

메시지 클래스들은 기본 타입, 구조체, 배열 그리고 Vector3와 같은 대부분이 Unity 엔진 타입을 갖는 멤버를 포함할 수 있습니다. 복잡한 클래스나 제너릭 컨테이너 멤버는 가질 수 없습니다.

일반적인 유형의 네트워크 메시지에 대한 내장 메시지 클래스도 있습니다:

  • EmptyMessage
  • StringMessage
  • IntegerMessage

메시지를 보내려면 NetworkClient, NetworkServer, NetworkConnection 클래스의 Send() 함수를 사용합니다. 이들은 모두 동일하게 작동합니다. 또한 Send 함수는 메시지 ID와 MessageBase에서 파생된 메시지 오브젝트를 받습니다. 아래의 코드에서는 내장 메시지 클래스 중 하나를 사용하여 메시지를 전송하고 처리하는 방법을 보여줍니다:

using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.NetworkSystem;

public class Begin : NetworkBehaviour
{
    const short MyBeginMsg = 1002;

    NetworkClient m_client;

    public void SendReadyToBeginMessage(int myId)
    {
        var msg = new IntegerMessage(myId);
        m_client.Send(MyBeginMsg, msg);
    }

    public void Init(NetworkClient client)
    {
        m_client = client;
        NetworkServer.RegisterHandler(MyBeginMsg, OnServerReadyToBeginMessage);
    }

    void OnServerReadyToBeginMessage(NetworkMessage netMsg)
    {
        var beginMessage = netMsg.ReadMessage<IntegerMessage>();
        Debug.Log("received OnServerReadyToBeginMessage " + beginMessage.value);
    }
}

사용자 정의의 네트워크 메시지 클래스를 선언하고 그것을 사용하려면:

using UnityEngine;
using UnityEngine.Networking;

public class Scores : MonoBehaviour
{
    NetworkClient myClient;

    public class MyMsgType {
        public static short Score = MsgType.Highest + 1;
    };

    public class ScoreMessage : MessageBase
    {
        public int score;
        public Vector3 scorePos;
        public int lives;
    }

    public void SendScore(int score, Vector3 scorePos, int lives)
    {
        ScoreMessage msg = new ScoreMessage();
        msg.score = score;
        msg.scorePos = scorePos;
        msg.lives = lives;

        NetworkServer.SendToAll(MyMsgType.Score, msg);
    }

    // Create a client and connect to the server port
    public void SetupClient()
    {
        myClient = new NetworkClient();
        myClient.RegisterHandler(MsgType.Connect, OnConnected);
        myClient.RegisterHandler(MyMsgType.Score, OnScore);
        myClient.Connect("127.0.0.1", 4444);
    }

    public void OnScore(NetworkMessage netMsg)
    {
        ScoreMessage msg = netMsg.ReadMessage<ScoreMessage>();
        Debug.Log("OnScoreMessage " + msg.score);
    }

    public void OnConnected(NetworkMessage netMsg)
    {
        Debug.Log("Connected to server");
    }
}

이 예제 코드에서는 ScoreMessage 클래스의 직렬화 코드는 없습니다. 직렬화 함수의 본체는 이 클래스를 위해 자동으로 생성됩니다.

에러 메시지 클래스

또한 MessageBase를 상속받은 ErrorMessage 클래스가 있습니다. 이 클래스는 클라이언트와 서버 상에서 에러 콜백으로 넘겨집니다.

ErrorMessage 클래스의 errorCode는 Networking.NetworkError 열거형과 일치합니다.

class MyClient
{
    NetworkClient client;
    
    void Start()
    {
        client = new NetworkClient();
        client.RegisterHandler(MsgType.Error, OnError);
    }
    
    void OnError(NetworkMessage netMsg)
    {
        var errorMsg = netMsg.ReadMessage<ErrorMessage>();
        Debug.Log("Error:" + errorMsg.errorCode);
    }
}
오브젝트 표시(Object Visibility)
Local Discovery