代码改变世界

Rpc简单入门

2018-07-31 09:40  李明成  阅读(1475)  评论(0编辑  收藏  举报

      RPC这个概念大家都应该很熟悉了,这里不在累述了;使用场景可以参考这篇,本篇主要分享下ThriftGrpc.Net Core环境下使用入门。Thirft或者Grps 都支持跨语言、跨平台的Rpc框架。编写IDL文件通过其强大的代码生成引擎生成C#代码,然后编写服务器端和客户端代码进行交互。

  •  Thrift 入门demo

创建两个控制台程序(client和service端)和一个类库,三个项目都分别安装thrift包;

Install-Package apache-thrift-netcore -Version 0.9.3.2;

简单实现一个远程调用用户中心服务,获取用户信息;

项目截图如下:

步骤1:下载Thrift放到指定盘;

  我的是放到E:\Thrift下。

步骤2:编写.thrift文件 

namespace csharp Thrift.Contract

service UserService{
   User Get(1:i32 id)
}

struct User
{
    1: required i64 Id;
    2: required string Name;
    4: optional string Remark;
}

步骤3:生成对应的代码 

 执行命令:thrift.exe --gen csharp UserServices.thrift

会看到生成的文件

把生成的项目拷到Thrift.Contract项目下; 并新增一个实现类

  public class UserServiceImpl : Iface
    {
        public User Get(int id)
        {
            return new User
            {
                 Id=1,
                 Name="成天",
                 Remark="热爱编程,热爱分享,热爱..."
            };
        }
    }

步骤4:编写服务端 

  private const int port = 8800;
        static void Main(string[] args)
        {
          
            Console.WriteLine("用户中心RPC Server已启动...");
            TServerTransport transport = new TServerSocket(port);
            var processor = new UserService.Processor(new UserServiceImpl());
            TServer server = new TThreadedServer(processor, transport);

            //如果多个服务实现的话,也可以这样启动;
            //var processor2 = new Manulife.DNC.MSAD.Contracts.PayoutService.Processor(new PayoutServiceImpl());
            //var processorMulti = new Thrift.Protocol.TMultiplexedProcessor();
            //processorMulti.RegisterProcessor("Service1", processor1);
            //processorMulti.RegisterProcessor("Service2", processor2);
            //TServer server = new TThreadedServer(processorMulti, transport);
            // lanuch
            server.Serve();
        }

步骤5:编写客户端

  static void Main(string[] args)
        {
            TTransport transport = new TSocket("localhost", 8800);
            TProtocol protocol = new TBinaryProtocol(transport);

            var client = new UserService.Client(protocol);
            transport.Open();

            var userResult = client.Get(1);

            Console.Write($"rpc->UserResult:{userResult.Name},{userResult.Remark}" );

            transport.Close();

            Console.ReadKey();
        }

然后运行服务端和客户端调用结果如下图:

  • Grpc 入门demo

Grpc代码工具通过nuget安装Grpc.Tools获取,把grpc_csharp_pluginprotoc放到对应的盘中;代码实现与thrift一样的需求;项目分别安装Grpc包

  • Install-Package Google.Protobuf -Version 3.6.0
  • Install-Package Grpc -Version 1.13.1

步骤1:编写.proto文件 

syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";

package Grpc.Contract;

 
service UserService {
   rpc GetUser (GetUserRequest) returns (GetUserResponse) {}
}

 
message GetUserRequest {
  int32 Id = 1;
}

 
message GetUserResponse {
     int64 Id=1;
     string Name=2;
     string Remark=3;
}

步骤2:生成对应的代码

执行命令:protoc.exe -I=. --csharp_out=. --grpc_out=. --plugin=protoc-gen-grpc=grpc_csharp_plugin.exe UserServices.proto

然后把生成的代码拷贝到Grpc.Contract;并新增一个实现类

  public class UserServiceImpl: UserService.UserServiceBase
    {

        public override Task<GetUserResponse> GetUser(GetUserRequest request, ServerCallContext context)
        {
            return Task.FromResult(new GetUserResponse {
                Id = 1,
                Name = "成天",
                Remark = "热爱编程,热爱分享,热爱..."
            });
        }
    }

步骤3:编写服务端

  const int port = 50051;
        static void Main(string[] args)
        {

            Console.WriteLine("用户中心RPC Server已启动...");
            Server server = new Server
            {
                Services = { UserService.BindService(new UserServiceImpl()) },
                Ports = { new ServerPort("localhost", port, ServerCredentials.Insecure) }
            };

            server.Start();
            Console.ReadKey();
        }

步骤4:编写客户端

    Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure);

            var client = new UserService.UserServiceClient(channel);

            var userResult = client.GetUser(new GetUserRequest{ Id = 1});
            Console.Write($"rpc->UserResult:{userResult.Name},{userResult.Remark}");
        
            channel.ShutdownAsync().Wait();
            Console.ReadKey();

然后运行服务端和客户端调用结果如下图:

到此这两种流行的rpc框架使用介绍完毕,是不是很简单。