Version: 2019.2
NetworkBehaviour 콜백
클라이언트 및 서버 처리

네트워크 메시지

참고: UNet은 지원이 중단되었으며 향후 Unity에서 삭제될 예정입니다. 현재 새로운 시스템이 개발 중입니다. 자세한 내용과 다음 단계는 이 블로그 포스트FAQ를 참조하십시오.

"고수준" 커맨드나 RPC 호출 이외에 로우 네트워크 메시지를 전송할 수도 있습니다.

확장을 통해 직렬화가 가능한 네트워크 메시지 클래스를 만들 수 있는 MessageBase가 제공됩니다. 이 클래스에는 작성기 및 판독기 오브젝트를 가져오는 SerializeDeserialize 함수가 포함되어 있습니다. 이러한 함수들은 직접 구현하거나 네트워킹 시스템이 자동으로 생성하는 코드 기반 구현을 사용할 수 있습니다. 기본 클래스는 아래와 같습니다.

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

메시지 클래스는 대부분의 일반적인 Unity 엔진 타입(예: Vector3)을 비롯하여 기본 타입, 구성 및 배열 멤버를 포함할 수 있습니다. 복잡한 클래스 또는 일반 컨테이너 멤버는 포함할 수 없습니다. 코드 기반 구현을 사용하는 경우에는 사용하는 타입이 공개적으로 표시되는지 확인해야 합니다.

네트워크 메시지 일반 유형에 대한 내장 메시지 클래스는 다음과 같습니다.

메시지를 보내려면 동일한 방식으로 동작하는 NetworkClient, NetworkServerNetworkConnection 클래스의 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 클래스에는 직렬화 코드가 없습니다. Unity가 이 클래스에 대한 직렬화 함수 바디를 자동으로 생성합니다.

ErrorMessage 클래스

MessageBase에서 파생된 ErrorMessage 클래스도 있습니다. 이 클래스는 클라이언트와 서버의 오류 콜백에 전달됩니다.

ErrorMessage 클래스의 errorCodeNetworking.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);
    }
}

NetworkBehaviour 콜백
클라이언트 및 서버 처리