.net core grpc 實現通信(一)


現在系統都服務化,.net core 實現服務化的方式有很多,我們通過grpc實現客戶端、服務端通信。

grpc(https://grpc.io/)是google發布的一個開源、高性能、通用RPC(Remote Procedure Call)框架,使用HTTP/2協議,支持多路復用,並用ProtoBuf作為序列化工具,提供跨語言、跨平台支持。下面以.net core演示如何使用grpc框架實現通信。

 

軟件版本

.net core:2.0

grpc:1.11.0

 

項目結構

InstallGrpc .net framework類庫 只為得到生成協議代碼工具protoc.exe、grpc_csharp_plugin.exe,沒有其他作用,如果已有工具,可以不用

Snai.GrpcClient 客戶端 .net core 2.0控制台程序

Snai.GrpcService.Hosting 服務端宿主 .net core 2.0控制台程序

Snai.GrpcService.Impl 協議方法實現  .net standard 2.0類庫

Snai.GrpcService.Protocol 生成協議方法 .net standard 2.0類庫

運行結果

服務端

客戶端

客戶端調用服務端求和方法成功。

 

項目實現

一、服務端

新建Snai.GrpcService解決方案

1、編寫協議

 新建 Snai.GrpcService.Protocol協議類庫項目,在 依賴項 右擊 管理NuGet程序包 瀏覽 找到 Grpc.Core 版本1.11.0,Google.Protobuf 版本3.5.1 包下載安裝

 在項目根目錄下新建一個 msg.proto 文件,打開 msg.proto 文件,在其中編寫基於proto3語言的協議代碼,用於自動生成到各語言協議,如果需要更深入的學習proto3語言可以打開該網站Proto3語言指南。msg.proto 代碼如下

 定義當前使用的是proto3語言並且包名(生成為C#則為命名空間):

syntax = "proto3";

package Snai.GrpcService.Protocol;

定義了1個服務,且有1個方法:

service MsgService{
  rpc GetSum(GetMsgNumRequest) returns (GetMsgSumReply){}
}

 方法的接收參數和返回參數

message GetMsgNumRequest {
  int32 Num1 = 1;
  int32 Num2 = 2;
}

message GetMsgSumReply {
  int32 Sum = 1;
}

 2、將協議生成C#代碼

生成協議代碼需 protoc.exe、grpc_csharp_plugin.exe工具,在.net framework 項目下引用安裝 Grpc.Tools 組件程序包,會得到protoc.exe、grpc_csharp_plugin.exe,但.net core 項目引用安裝是不會下載工具到項目目錄的,所以我們需要建一個.net framework項目,我建了個 InstallGrpc .net framework類庫 用於引用安裝得到工具。

這里得到工具有個小插曲,引用Grpc.Tools版本1.11.0得到protoc.exe、grpc_csharp_plugin.exe 拷到 Snai.GrpcService.Protocol 目錄下生成不了,我再引用Google.Protobuf.Tools版本3.5.1里面有 protoc.exe,用 Grpc.Tools下的 grpc_csharp_plugin.exe, Google.Protobuf.Tools下protoc.exe 根據當前系統選擇,拷貝到 Snai.GrpcService.Protocol 目錄下。

先用Grpc.Tools 下的,如果生成不了,再用 Grpc.Tools下的 grpc_csharp_plugin.exe, Google.Protobuf.Tools下protoc.exe

然后在項目中新建一個名為ProtocGenerate.cmd的文件,在其中輸入以下指令:

protoc -I . --csharp_out . --grpc_out . --plugin=protoc-gen-grpc=grpc_csharp_plugin.exe msg.proto

然后直接雙擊運行,項目下生成了“Msg.cs”和“MsgGrpc.cs”兩個文件,這樣協議部分的所有工作就完成了,最終項目結構如下:

 3、編寫協議實現代碼

 新建Snai.GrpcService.Impl實現類庫項目,在 依賴項 下載安裝Grpc.Core 包,項目引用Snai.GrpcService.Protocol

 在項目根目錄下新建 MsgServiceImpl.cs 類文件,繼承 MsgService.MsgServiceBase 協議類,實現服務方法,代碼如下:

using Grpc.Core;
using Snai.GrpcService.Protocol;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace Snai.GrpcService.Impl
{
    public class MsgServiceImpl: MsgService.MsgServiceBase
    {
        public MsgServiceImpl()
        {
        }

        public override async Task<GetMsgSumReply> GetSum(GetMsgNumRequest request, ServerCallContext context)
        {
            var result = new GetMsgSumReply();

            result.Sum = request.Num1 + request.Num2;

            return result;
        }
    }
}

 在項目根目錄下新建 RpcConfig.cs 類文件,編寫綁定服務到服務端,服務端 地址 端口 等信息,實現啟動方法,代碼如下:

using Grpc.Core;
using Snai.GrpcService.Protocol;
using System;
using System.Collections.Generic;
using System.Text;

namespace Snai.GrpcService.Impl
{
    public static class RpcConfig
    {
        private static Server _server;

        public static void Start()
        {
            _server = new Server
            {
                Services = { MsgService.BindService(new MsgServiceImpl()) },
                Ports = { new ServerPort("localhost", 40001, ServerCredentials.Insecure) }
            };
            _server.Start();

            Console.WriteLine("grpc ServerListening On Port 40001");
            Console.WriteLine("任意鍵退出...");
            Console.ReadKey();

            _server?.ShutdownAsync().Wait();
        }
    }
}

 最終項目結構如下:

4、編寫服務端啟動程序

 新建Snai.GrpcService.Hosting 控制台程序,項目引用Snai.GrpcService.Impl

 打開 Program.cs 文件,修改 Main 方法,加入服務啟動,代碼如下:

using Snai.GrpcService.Impl;
using System;

namespace Snai.GrpcService.Hosting
{
    class Program
    {
        static void Main(string[] args)
        {
            RpcConfig.Start();
        }
    }
}

 最終項目結構如下:

到此服務端所有代碼已編寫完成,下面開始編寫客戶端。

二、客戶端

 新建Snai.GrpcClient 控制台程序,在 依賴項 下載安裝Grpc.Core 包,項目引用Snai.GrpcService.Protocol

 在項目根目錄下新建 MsgServiceClient.cs 類文件,編寫與服務端通信的 地址 端口 等信息,並調用服務端方法,代碼如下:

using Grpc.Core;
using Snai.GrpcService.Protocol;
using System;
using System.Collections.Generic;
using System.Text;

namespace Snai.GrpcClient
{
    public static class MsgServiceClient
    {
        private static Channel _channel;
        private static MsgService.MsgServiceClient _client;

        static MsgServiceClient()
        {
            _channel = new Channel("127.0.0.1:40001", ChannelCredentials.Insecure);
            _client = new MsgService.MsgServiceClient(_channel);
        }

        public static GetMsgSumReply GetSum(int num1, int num2)
        {
            return _client.GetSum(new GetMsgNumRequest
            {
                Num1 = num1,
                Num2 = num2
            });
        }
    }
}

 打開 Program.cs 文件,修改 Main 方法,得到服務端返回結果,顯示結果,代碼如下:

using Snai.GrpcService.Protocol;
using System;

namespace Snai.GrpcClient
{
    class Program
    {
        static void Main(string[] args)
        {
            GetMsgSumReply msgSum = MsgServiceClient.GetSum(10, 2);

            Console.WriteLine("grpc Client Call GetSum():" + msgSum.Sum);

            Console.WriteLine("任意鍵退出...");
            Console.ReadKey();
        }
    }
}

 最終項目結構如下:

 

到此所有代碼都已編寫完成

三、啟動

右擊生成解決方案,生成完成后,先啟動服務端,再啟動客戶端

命令行到服務端目錄 Snai.GrpcService.Hosting\bin\Debug\netcoreapp2.0\,用命令 dotnet Snai.GrpcService.Hosting.dll 啟動服務端

命令行到客戶端目錄 Snai.GrpcClient\bin\Debug\netcoreapp2.0\,用命令 dotnet Snai.GrpcClient.dll 啟動客戶端

 

客戶端調用服務端方法成功,實現grpc

它們之間是通過Grpc.Core中的 Server 和 Channel 來通信

Github源碼地址:https://github.com/Liu-Alan/Snai.GrpcService

博客地址:http://www.snaill.net/post/1

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM