Version: 2019.3
언어: 한국어
NetworkBehaviour 콜백
클라이언트 및 서버 처리

네트워크 메시지

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

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

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

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, NetworkServer 및 NetworkConnection 클래스의 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 클래스의 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);
    }
}

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