美文网首页网络传输
Unity中使用ProtoBuff3.0,与netty服务器通信

Unity中使用ProtoBuff3.0,与netty服务器通信

作者: 极限小黑 | 来源:发表于2017-06-29 12:32 被阅读0次

    [TOC]

    1. Unity protobuff3.0库的选择

    网上搜查发现,目前可供unity使用的protobuff3.0的库主要有2个,一个是
    protobuf-net,另一个是
    protobuf3-for-unity,选择哪一个呢?

    • 从github上的Star数量来看:protobuf-net的1400+远胜于protobuf3-for-unity的136
    • 从更新日期来看,protobuf-net最近几天都有post,而protobuf3-for-unity最近的动作则是在十个月之前了。

    但是为什么最终选择了protobuf3-for-unity?因为我使用Nuget :

    Install-Package protobuf-net

    安装protobuf-net一直不成功,报错说指令集不兼容,我们知道,unity支持的.net版本是2.0和3.5,protobuf-net最新支持的是.NET Framework 4.0+的,没法用,官网上说v2.1.0的版本支持.NET Framework 2.0/3.0/3.5,于是安装命令改成:

    Install-Package protobuf-net -version 2.1.0

    还是报一样的错误:

    Install-Package protobuf-net

    正在尝试收集与目标为“.NETFramework,Version=v3.5,Profile=Unity Subset v3.5”的项目“TestMj”有关的>包“protobuf-net.2.2.1”的依赖项信息
    收集依赖项信息花费时间 1.11 ms
    正在尝试解析程序包“protobuf-net.2.2.1”的依赖项,DependencyBehavior 为“Lowest”
    解析依赖项信息花费时间 0 ms
    正在解析操作以安装程序包“protobuf-net.2.2.1”
    已解析操作以安装程序包“protobuf-net.2.2.1”
    从“nuget.org”检索包“protobuf-net 2.2.1”
    GET https://api.nuget.org/packages/protobuf-net.2.2.1.nupkg
    OK https://api.nuget.org/packages/protobuf-net.2.2.1.nupkg 69 毫秒
    正在安装 protobuf-net 2.2.1。
    安装失败。正在回滚...
    程序包“protobuf-net.2.2.1”不存在于项目“TestMj”中
    程序包“protobuf-net.2.2.1”不存在于文件夹“C:\Users\IGG\AppData\Local\Temp\TestMj\packages”中
    执行 nuget 操作花费时间 701.07 ms
    Install-Package : 无法安装程序包“protobuf-net 2.2.1”。你正在尝试将此程序包安装到目标为“.NETFramework,Version=v3.5,Profile=Unity Subset v3.5”的项目中,但该程序包不包含任何与该框架兼容的程序集引用或内容文件。有关详细信息,请联系程序包作者。
    所在位置 行:1 字符: 16

    • Install-Package <<<< protobuf-net
      • CategoryInfo : NotSpecified: (:) [Install-Package], Exception
      • FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand

    已用时间: 00:00:01.6763018

    参考这个最新版的release note里面,好像是有针对这个问题做修复,但是我试了Install-Package protobuf-net -version 2.3.0-alpha没效果,不知道是不是用法不对,不想继续浪费时间,就果断选择protobuf3-for-unity。等下次闲了再去试试。

    v2.3.0-alpha

    • net20 / net35 targets reinstated for NuGet build (#262)

    2. Unity protobuff3.0整合及测试

    整合:

    1. 新建一个unity3d项目
    2. 下载protobuf3-for-unity,解压。
    3. 根据项目首页readme.md的指示,安装对应版本的.NET Core
    4. 双击解压后的得到的build_packages.bat,进行编译,如果编译失败,一定是.Net Core版本选择错了,卸载掉原来的重新下载一个安装再试。
    5. 编译成功的话,protobuf3-for-unity-3.0.0\src\Google.Protobuf\bin\Release\net35目录下会有一个Google.Protobuf.dll,这个dll就是我们要用在unity项目里面的。如果自己编译不出来,也可以在这里直接下载,解压里面就有一个作者编好的dll。
    6. 把上面的dll拷贝到unity项目的Assets\Plugins\目录下。如果没有Plugins目录,自己创建一个。

    注:protobuf3-for-unity-3.0.0\src\Google.Protobuf工程源码可以看看,有助于了解protobuff3.0的实现。

    测试:

    • 在测试之前,还需要下载一个protoc,也就是代码生成器,用来把我们定义的proto文件生成C#对应的类,我们是protobuff3.0版本,要选对版本、选对系统,我是win7系统,所以是下载这个protoc-3.0.0-win32.zip,注意需要的是protoc,不需要把源代码下载下来。源代码在上面下载的protobuf3-for-unity里面已经有了。解压后在protoc-3.0.0-win32\bin目录下能看到一个protoc.exe
    • 把下面代码保存成addressbook.proto文件放在protoc.exe同级目录下
    syntax = "proto3";
    package tutorial;
    
    message Person {
      string name = 1;
      int32 id = 2;  // Unique ID number for this person.
      string email = 3;
    
      enum PhoneType {
        MOBILE = 0;
        HOME = 1;
        WORK = 2;
      }
    
      message PhoneNumber {
        string number = 1;
        PhoneType type = 2;
      }
    
      repeated PhoneNumber phones = 4;
    }
    
    // Our address book file is just one of these.
    message AddressBook {
      repeated Person people = 1;
    }```
    - 打开一个cmd窗口,cd到protoc.exe所在目录,输入``` protoc --csharp_out=./ addressbook.proto ```然后回车,可以看到,同级目录下生成了一个Addressbook.cs文件,这个文件需要加在unity3d工程的Assets\Scripts目录下,不放在Scripts目录下应该也没影响。
    - 新建一个C#脚本,挂在场景任意一个物体上,只要启动的时候能触发这个脚本的调用就可以了。
    - 在新建的脚本的Start函数里写上测试代码:
    
    ``` C#
    // 我的全部using是这些,因为已经添加了网络部分的,虽然到这一步还没用到
    using Google.Protobuf;
    using Google.Protobuf.Examples.AddressBook;
    using Google.Protobuf.WellKnownTypes;
    using System;
    using System.IO;
    using System.Net.Sockets;
    using UnityEngine;
    
    void Start () {
            // 这些代码是在protobuf3-for-unity-3.0.0\src\AddressBook\Program.cs里面拷贝的
            byte[] bytes;
            // Create a new person
            Person person = new Person
            {
                Id = 1,
                Name = "Foo",
                Email = "foo@bar",
                Phones = { new Person.Types.PhoneNumber { Number = "555-1212" } }
            };
            using (MemoryStream stream = new MemoryStream())
            {
                // Save the person to a stream
                person.WriteTo(stream);
                bytes = stream.ToArray();
            }
            Person copy = Person.Parser.ParseFrom(bytes);
    
            AddressBook book = new AddressBook
            {
                People = { copy }
            };
            bytes = book.ToByteArray();
            // And read the address book back again
            AddressBook restored = AddressBook.Parser.ParseFrom(bytes);
            // The message performs a deep-comparison on equality:
            if (restored.People.Count != 1 || !person.Equals(restored.People[0]))
            {
                throw new Exception("There is a bad person in here!");
            }
        }
    
    • 添加完以上代码,在ide里打个断点,unity里面点启动,一步步断点跟下来可以查看究竟。

    3. 建立与服务端通信连接,使用protobuff编码解码

    4. 处理与Netty服务器通信的粘包、拆包

    先去吃饭,3和4部分放在下一篇

    相关文章

      网友评论

        本文标题:Unity中使用ProtoBuff3.0,与netty服务器通信

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