在上一篇文章中,介紹了如何在Unity中啟動(dòng)服務(wù)端和客戶端以及客戶端連接服務(wù)端的方法,接下來,將通過自定義消息類型,實(shí)現(xiàn)服務(wù)端與客戶端之間的通信.
1.自定義消息類型(CustomMsgTypes)
其實(shí)在上一篇文章中,已經(jīng)知道如何注冊(cè)消息回調(diào)了,就是使用RegisterHandler
方法,這個(gè)方法的第一個(gè)參數(shù)short
類型的變量,第二個(gè)參數(shù)是NetworkMessageDelegate
類型的委托,如果消息注冊(cè)方法,我們就可以自定義MsgType,來處理游戲內(nèi)的邏輯.代碼如下
public class CustomMsgTypes
{
public const short InGameMsg = 1003;
}
這個(gè)消息的定義,需要注意UnityEngine.Networking下內(nèi)置的MsgType已經(jīng)占用了一些數(shù)值,避免與Unity自帶的MsgType重復(fù).然后把CustomMsgTypes注冊(cè)到網(wǎng)絡(luò)組件的消息回調(diào):
// 在服務(wù)端注冊(cè)消息
public override void RegisterMsgHandles()
{
// 注冊(cè)自定義消息類型
NetworkServer.RegisterHandler(CustomMsgTypes.InGameMsg, OnRecvCustomMsg);
}
// 回調(diào)方法
protected void OnRecvCustomMsg(NetworkMessage netMsg)
{
Debug.LogWarning("OnRecvCustomMsg");
}
2.定義自定義消息
已經(jīng)定義了消息類型,接下來,要定義這個(gè)消息類型對(duì)應(yīng)的消息內(nèi)容,在UnityEngine.Networking組件下,定義的Message要繼承自MessageBase,基類有兩個(gè)方法 Deserialize
和 Serialize
需要重寫,也就是消息的序列化和反序列化.代碼如下:
public class CustomMessage : MessageBase
{
public int messageId;
public string content;
public Vector3 vector;
public byte[] bytes;
public override void Serialize(NetworkWriter writer)
{
writer.Write(messageId);
writer.Write(content);
writer.Write(vector);
writer.WriteBytesAndSize(bytes, bytes.Length);
}
public override void Deserialize(NetworkReader reader)
{
messageId = reader.ReadInt32();
content = reader.ReadString();
vector = reader.ReadVector3();
ushort count = reader.ReadUInt16();
bytes = reader.ReadBytes(count);
}
}
需要注意的是 Serialize
方法是msg在發(fā)送的時(shí)候自動(dòng)調(diào)用的,而Deserialize
方法需要在收到消息包的時(shí)候主動(dòng)調(diào)用:
protected void OnRecvCustomMsg(NetworkMessage netMsg)
{
CustomMessage msg = new CustomMessage();
msg.Deserialize(netMsg.reader);
Debug.LogWarning("OnRecvCustomMsg");
Debug.LogWarning("messageId:"+msg.messageId);
Debug.LogWarning("content:"+msg.content);
Debug.LogWarning("vector:" + msg.vector);
Debug.LogWarning("bytesLength:" + msg.bytes.Length);
}
3. 發(fā)送自定義消息
好了,現(xiàn)在自定義消息的類型與消息內(nèi)容都有了,現(xiàn)在我們只需要在客戶端往消息里填充數(shù)據(jù),執(zhí)行NetworkConnection.Send
方法就可以發(fā)送消息了.
// 發(fā)送消息
public void Send()
{
CustomMessage message = new CustomMessage();
message.messageId = Time.frameCount;
message.content = "I am Client!";
message.vector = new Vector3(0,5,0);
message.bytes = new byte[100];
connection.Send(CustomMsgTypes.InGameMsg, message); // 使用Unity的NetworkConnection來發(fā)送消息
}
在服務(wù)端,就可以接受到消息,通過Deserialize
可以獲取到消息內(nèi)容.
4.小結(jié)
通過上述的例子,實(shí)現(xiàn) 服務(wù)端注冊(cè)自定義消息 => 客戶端構(gòu)造消息并發(fā)送 => 服務(wù)端接收解析獲取數(shù)據(jù) ,如果想要把服務(wù)端的消息發(fā)到客戶端,也是這個(gè)流程.
下一篇文章將通過目前網(wǎng)上別的游戲的同步架構(gòu)來探討<游戲中網(wǎng)絡(luò)同步的解決方案>,敬請(qǐng)期待.