コマンドと 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) {}
}
メッセージクラスは、ベーシックタイプ・構造体・配列のメンバや、Unity のほとんどの通常エンジンタイプ(Vector3 など)のメンバを含むことができます。複雑なクラスやジェネリックのコンテナのメンバは含むことができません。
一般的なタイプのネットワークメッセージのためのビルトイン メッセージクラスもあります(以下)。
メッセージを送信するには、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 クラス用のシリアライゼーションコードはありません。このクラスのシリアライゼーション機能は自動的に作成されます。
ErrorMessage クラスもあり、これは MessageBase から派生されます。このクラスは、クライアントおよびサーバーのエラーコールバックへパスされます。
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);
}
}