.net core grpc 實現通訊(一)

如今系統都服務化,.net core 實現服務化的方式有不少,咱們經過grpc實現客戶端、服務端通訊。git

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

 

軟件版本 app

.net core:2.0框架

grpc:1.11.0 async

 

項目結構ide

InstallGrpc .net framework類庫 只爲獲得生成協議代碼工具protoc.exe、grpc_csharp_plugin.exe,沒有其餘做用,若是已有工具,能夠不用
工具

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

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

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

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

運行結果

服務端

客戶端

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

 

項目實現

1、服務端

新建Snai.GrpcService解決方案

一、編寫協議

 新建 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;
}

 二、將協議生成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」兩個文件,這樣協議部分的全部工做就完成了,最終項目結構以下:

 三、編寫協議實現代碼

 新建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();
        }
    }
}

 最終項目結構以下:

四、編寫服務端啓動程序

 新建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();
        }
    }
}

 最終項目結構以下:

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

2、客戶端

 新建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();
        }
    }
}

 最終項目結構以下:

 

到此全部代碼都已編寫完成

3、啓動

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

命令行到服務端目錄 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 來通訊

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

相關文章
相關標籤/搜索