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

上一篇文章中,介绍了如何在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.小结

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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 137,033评论 19 139
  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AI阅读 16,334评论 3 119
  • 失恋笔记 2018年2月22日 你突然消失的 ,第7天 。 从最初的愤怒 ,失望 ,不甘心转为担忧和怀念。 说服不...
    给你的备注是十二阅读 385评论 0 0
  • 孩子就像家庭的一面镜子,会真实反映出家中的情况,其中最直接反映出的是父母的「身教」,因为孩子会模仿父母的言行及如何...
    系统排列阅读 242评论 0 0
  • 突然的暴雨,瞬间的宁静。躺在地上,迎着夹带雨雾的凉风,音乐伴着雨声…
    棉花一朵朵阅读 220评论 0 0

友情链接更多精彩内容