고수준 기능 커맨드나 RPC 호출 이외에도, 로우 네트워크 메시지를 전송할 수도 있습니다.
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 엔진 타입인 멤버를 포함할 수 있습니다. 복잡한 클래스나 일반 컨테이너는 멤버로 포함할 수 없습니다.
네트워크 메시지 일반 유형에 대한 내장 메시지 클래스는 다음과 같습니다.
메시지를 보내려면 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 클래스에는 직렬화 코드가 없습니다. 직렬화 함수 바디는 자동으로 이 클래스에 대해 생성됩니다.
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);
}
}