Unity中使用gRPC进行数据交互

gPRC简介

在gRPC中,客户端应用程序可以直接在其他计算机的服务器应用程序上调用方法,就好像它是本地对象一样,这使您更轻松地创建分布式应用程序和服务。与许多RPC系统一样,gRPC围绕定义服​​务的思想,指定可通过其参数和返回类型远程调用的方法。在服务器端,服务器实现此接口并运行gRPC服务器以处理客户端调用。在客户端,客户端具有一个stub(在某些语言中仅称为客户端),提供与服务器相同的方法。
gRPC简介
从Google内部的服务器到您自己的台式机,gRPC客户端和服务器可以在各种环境中运行并相互通信,并且可以使用gRPC支持的任何语言编写。因此,例如,您可以使用Go,Python或Ruby的客户端轻松地用Java创建gRPC服务器。此外,最新的Google API的接口将具有gRPC版本,可让您轻松地在应用程序中内置Google功能。
默认情况下,gRPC使用协议缓冲区,这是Google成熟的开源机制,用于序列化结构化数据(尽管它可以与其他数据格式(例如JSON)一起使用)。

gRPC优势

  1. 性能好
  2. 代码可以自动生成
  3. 有严格的接口规范
  4. 可以支持流式传输
  5. 方便设置超时/截止时间

gRPC劣势

  1. 浏览器支持有限
  2. 人类不可读

推荐使用的场景

  1. 微服务
  2. 点对点实时通信
  3. 多语言混合开发环境
  4. 网络受限环境

不推荐使用场景

  1. 浏览器可访问的API
  2. 广播实时通信
  3. 进程间通信

点击查看以上四部分详情

gRPC接口定义

gRPC将内容保存到.proto文件中,通过固定的格式进行接口的定义。

syntax = "proto3";

package helloworld;

// The greeter service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

gRPC客户端和服务端发送数据一般有两种形式,分别是一次只发送一个包(Unary)和一次发送多个包(Streaming),通过这两种形式可以组合成四种接口类型,分别是Unary-Unary、Streaming-Streaming、Unary-Streaming、Streaming-Unary。

gRPC数据类型

gRPC基于Proto3语法进行定义,可以定义多种数据类型。详情可点击这里

  1. 值类型
    值类型
  2. 各类数据默认值
For strings, the default value is the empty string.
For bytes, the default value is empty bytes.
For bools, the default value is false.
For numeric types, the default value is zero.
For enums, the default value is the first defined enum value, which must be 0.
For message fields, the field is not set. Its exact value is language-dependent. See the generated code guide for details.
  1. 枚举类型
//枚举类型第一个值必须为0
message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
  enum Corpus {
    UNIVERSAL = 0;
    WEB = 1;
    IMAGES = 2;
    LOCAL = 3;
    NEWS = 4;
    PRODUCTS = 5;
    VIDEO = 6;
  }
  Corpus corpus = 4;
}
  1. Maps类型
map<key_type, value_type> map_field = N;
  1. 字段修饰符
    required:值不可为空
    optional:可选字段
    singular:符合语法规则的消息包含零个或者一个这样的字段(最多一个)
    repeated:一个字段在合法的消息中可以重复出现一定次数(包括零次)。重复出现的值的次序将被保留。在proto3中,重复出现的值类型字段默认采用压缩编码。
  2. JSON Mapping
    在这里插入图片描述

创建gRPC工程

  1. 新建VS项目
    在这里插入图片描述
    在这里插入图片描述
  2. 设置该项目为类库
    在这里插入图片描述
  3. 新建Server和Client项目,通过NUGET添加gRPC依赖(Grpc、Grpc.Tools、Google.Protouf)
    在这里插入图片描述
    在这里插入图片描述
  4. 添加.proto接口文件
    在这里插入图片描述
  5. 在GrpcForUnity中添加自动生成代码配置
  <ItemGroup>
    <Protobuf Include="**/*.proto" />
  </ItemGroup>

详情请点击这里
在这里插入图片描述
添加完成后手动生成解决方案,会在

..\GrpcForUnity\GrpcForUnity\obj\Debug\netcoreapp2.1

文件夹中生成类文件
在这里插入图片描述

  1. 为Server和Client项目添加对GrpcForUnity项目的引用
    在这里插入图片描述
  2. 在Server中写入服务端代码
using System;
using System.Threading.Tasks;
using Grpc.Core;
using Helloworld;

namespace GrpcForUnityServer
{

    class SayHelloImpl : SayHello.SayHelloBase
    {
        public override Task<HelloReply> SayHelloToUnity(HelloRequest request, ServerCallContext context)
        {
            return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Server server = new Server
            {
                Services = { SayHello.BindService(new SayHelloImpl()) },
                Ports = { new ServerPort("localhost", 50051, ServerCredentials.Insecure) }
            };
            server.Start();
            Console.WriteLine("Server Start On Locolhost:50051");
            Console.WriteLine("Press any key to stop the server...");
            Console.ReadKey();
            server.ShutdownAsync().Wait();
        }
    }
}

手动生成解决方案,在Server项目下的\GrpcForUnityServer\bin\Debug\netcoreapp2.1\文件中按住Shift右击,调出PowerShell窗口,输入

dotnet exec GrpcForUnityServer.dll

启动服务

在这里插入图片描述

gRPC客户端代码

在客户端编写请求代码

扫描二维码关注公众号,回复: 16178370 查看本文章
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using Grpc.Core;
using Helloworld;

namespace GrpcForUnityClient
{
    class Program
    {
        public static void Main(string[] args)
        {
            Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure);

            var client = new SayHello.SayHelloClient(channel);
            String user = "you";

            var reply = client.SayHello(new HelloRequest { Name = user });
            Console.WriteLine("Greeting: " + reply.Message);

            channel.ShutdownAsync().Wait();
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
}

手动生成解决方案,以启动服务器同样的方式启动客户端,便可看到获取的结果。

gRPC Unity端代码

  1. 新建Unity项目,在这里下载Unity可用的gRPC包并导入工程
    在这里插入图片描述
  2. 新建UI界面用于测试
    在这里插入图片描述
  3. 将自动生成的Helloworld.cs和HelloworldGrpc.cs两个脚本从VS工程中导入Unity中,新建Test脚本,代码如下:
using Grpc.Core;
using Helloworld;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour
{
   public Text Response;
  public void Send()
   {
       try
       {
           Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure);

           var client = new SayHello.SayHelloClient(channel);
           string user = "My Friends";

           var reply = client.SayHelloToUnity(new HelloRequest { Name = user });

           Response.text = reply.Message;

           channel.ShutdownAsync().Wait();
       }
       catch (System.Exception e)
       {
           Response.text = e.ToString();
       }
       
   }
}

将脚本挂载在Button上并对Text和Button点击事件赋值

  1. 运行Unity测试即可。
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/beihuanlihe130/article/details/103615083