美文网首页网络编程游戏同步unity
[从零开始的Unity网络同步] 2.服务端与客户端之间通信

[从零开始的Unity网络同步] 2.服务端与客户端之间通信

作者: 烂笔头_27 | 来源:发表于2018-11-02 14:38 被阅读83次

    上一篇文章中,介绍了如何在Unity中启动服务端和客户端以及客户端连接服务端的方法,接下来,将通过自定义消息类型,实现服务端与客户端之间的通信.

    1.自定义消息类型(CustomMsgTypes)

    其实在上一篇文章中,已经知道如何注册消息回调了,就是使用RegisterHandler方法,这个方法的第一个参数short类型的变量,第二个参数是NetworkMessageDelegate类型的委托,如果消息注册方法,我们就可以自定义MsgType,来处理游戏内的逻辑.代码如下

    public class CustomMsgTypes
    {
        public const short InGameMsg = 1003;
    }
    

    这个消息的定义,需要注意UnityEngine.Networking下内置的MsgType已经占用了一些数值,避免与Unity自带的MsgType重复.然后把CustomMsgTypes注册到网络组件的消息回调:

    // 在服务端注册消息
    public override void RegisterMsgHandles()
    {
        // 注册自定义消息类型
        NetworkServer.RegisterHandler(CustomMsgTypes.InGameMsg, OnRecvCustomMsg);
    }
    // 回调方法
    protected void OnRecvCustomMsg(NetworkMessage netMsg)
    {
        Debug.LogWarning("OnRecvCustomMsg");
    }
    

    2.定义自定义消息

    已经定义了消息类型,接下来,要定义这个消息类型对应的消息内容,在UnityEngine.Networking组件下,定义的Message要继承自MessageBase,基类有两个方法 DeserializeSerialize 需要重写,也就是消息的序列化和反序列化.代码如下:

    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在发送的时候自动调用的,而Deserialize方法需要在收到消息包的时候主动调用:

    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. 发送自定义消息

    好了,现在自定义消息的类型与消息内容都有了,现在我们只需要在客户端往消息里填充数据,执行NetworkConnection.Send方法就可以发送消息了.

    // 发送消息
    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来发送消息
    }
    

    在服务端,就可以接受到消息,通过Deserialize可以获取到消息内容.

    1.png

    4.小结

    通过上述的例子,实现 服务端注册自定义消息 => 客户端构造消息并发送 => 服务端接收解析获取数据 ,如果想要把服务端的消息发到客户端,也是这个流程.
    下一篇文章将通过目前网上别的游戏的同步架构来探讨<游戏中网络同步的解决方案>,敬请期待.

    相关文章

      网友评论

        本文标题:[从零开始的Unity网络同步] 2.服务端与客户端之间通信

        本文链接:https://www.haomeiwen.com/subject/yezqxqtx.html