C#中使用gRPC通訊的示例詳解
在c#中使用gRPC通訊
包括:GRPC文件的創(chuàng)建生成、服務(wù)端和客戶端函數(shù)類庫的封裝、創(chuàng)建服務(wù)端和客戶端調(diào)用測試。
創(chuàng)建并生成GRPC服務(wù)文件
- 創(chuàng)建新項目控制臺應(yīng)用 , 項目名稱(MgRPC)
- 安裝三個nuget包 Google.Protobuf , Grpc.Core , Grpc.Tools
- 項目添加新建項,選擇類,修改名稱為Link.proto,添加后把Link.proto里面內(nèi)容清空
定義Protocol
添加代碼。測試實例為服務(wù)端和客戶端傳輸字符串消息,只定義了一個方法(客戶端調(diào)用,服務(wù)端重寫),傳輸內(nèi)容包括請求字符串和回復(fù)字符串。此處可自行定義。
syntax = "proto3";//proto3 是 Protocol Buffers 的第三個版本 // 指定了生成的 C# 代碼的命名空間為 LinkService。當(dāng)使用 protobuf 編譯器 (protoc) 將這個 .proto 文件轉(zhuǎn)換為 C# 代碼時,生成的類將位于 LinkService 命名空間中 option csharp_namespace = "LinkService"; //定義了一個名為 Link 的 gRPC 服務(wù)。在 gRPC 中,服務(wù)是由一個或多個 RPC 方法組成的 service Link { //定義了一個 RPC 方法。這個方法名為 GetMessage,它接受一個 Mes 類型的消息作為參數(shù), //并返回一個 Mes 類型的消息。在 gRPC 中,客戶端可以調(diào)用這個方法,并發(fā)送一個 Mes 消息給服務(wù)端,然后服務(wù)端會處理這個消息并返回一個 Mes 消息給客戶端。 rpc GetMessage(Mes) returns (Mes); } //定義了一個名為 Mes 的消息類型。在 protobuf 中,消息是由一系列字段組成的,每個字段都有一個名稱、一個類型和一個標(biāo)識符。 message Mes { // 客戶端發(fā)送 // 定義了一個名為 StrRequest 的字段,類型為 string,標(biāo)識符為 1。這個標(biāo)識符在消息內(nèi)部是唯一的,并且一旦分配就不能更改,因為它被用于序列化和反序列化過程中的字段識別。 string StrRequest = 1; // 同樣定義了一個名為 StrReply 的字段,類型為 string,標(biāo)識符為 2。(服務(wù)端回復(fù)) string StrReply = 2; }
設(shè)置Link.proto
右鍵Link.proto文件選擇屬性,生成操作選擇如圖:
生成cs文件代碼
生成解決方案。在下圖路徑得到自動生成的兩個類。
至此,獲得GRPC服務(wù)需要的三個文件:Link.proto、Link.cs、LinkGrpc.cs??梢詫⑦@三個文件放在一個項目中直接使用,需要重寫一下服務(wù)端方法、創(chuàng)建服務(wù)端和客戶端的啟動方法。但是如果不同的項目軟件之間通訊需要各自如此開發(fā)??梢韵确庋b成一個GRPC類庫供其他項目直接調(diào)用。
服務(wù)端和客戶端類庫的封裝
- 創(chuàng)建類庫(.NET Framework)項目 , 項目名稱(GrpcLink)
- 項目添加現(xiàn)有項,上面獲得的三個文件(Link.cs , LinkGrpc.cs)。安裝nuget包:Grpc.Core和Google.Protobuf。
- 創(chuàng)建兩個類:LinkFunc用于放此類庫可用于外部引用調(diào)用的方法。LinkServerFunc基于Link.LinkBase,用于重寫在proto文件中定義的方法。
對于不同的項目,在客戶端請求時,服務(wù)端要根據(jù)自身情況回復(fù)想回的內(nèi)容,因此可以提供一個委托供外部自行開發(fā)回復(fù)函數(shù)。
在LinkFunc類中定義如下:
public static Func<string, string> ReplyMes;
LinkServerFunc
在LinkServerFunc類重寫GetMessage方法如下
using Grpc.Core; using LinkService; using System.Threading.Tasks; using static LinkService.Link; namespace GrpcLink { /// <summary> /// 重寫在proto文件中定義的方法 /// </summary> public class LinkServerFunc : LinkBase { public override Task<Mes> GetMessage(Mes request,ServerCallContext context) { Mes mes = new Mes(); mes.StrReply = LinkFunc.ReplyMes(request.StrRequest); return Task.FromResult(mes); } } }
LinkFunc
using Grpc.Core; using LinkService; using System; using static LinkService.Link; namespace GrpcLink { public class LinkFunc { /// <summary> /// 用于服務(wù)端回復(fù)委托 /// </summary> public static Func<string,string> ReplyMes; // 定義服務(wù)端和客戶端 public static Server LinkServer; public static LinkClient LinkClient; /// <summary> /// 服務(wù)端啟動 /// </summary> /// <param name="host"></param> /// <param name="port"></param> public static void LinkServerStart(string host,int port) { LinkServer = new Server { Services = { BindService(new LinkServerFunc()) }, Ports = { new ServerPort(host,port,ServerCredentials.Insecure) } }; LinkServer.Start(); } /// <summary> /// 服務(wù)端關(guān)閉 /// </summary> public static void LinkServerClose() { LinkServer?.ShutdownAsync().Wait(); } /// <summary> /// 客戶端啟動 /// </summary> /// <param name="strIp"></param> public static void LinkClientStart(string strIp) { Channel prechannel = new Channel(strIp,ChannelCredentials.Insecure); LinkClient = new LinkClient(prechannel); } /// <summary> /// 客戶端發(fā)送消息函數(shù) /// </summary> /// <param name="strRequest"></param> /// <returns></returns> public static string SendMes(string strRequest) { Mes mes = new Mes(); mes.StrRequest = strRequest; var res = LinkClient.GetMessage(mes); return res.StrReply; } } }
生成引用庫
生成解決方案。Debug中可以得到項目的dll文件GrpcLink.dll,其他項目可以引用使用了。
創(chuàng)建服務(wù)端和客戶端調(diào)用測試
- 創(chuàng)建兩個控制臺(.NET Framework)項目 , 項目名稱TestCilent , TestServer
- 將上述GrpcLink.dll文件分別放入兩個項目中,并添加dll引用。 如果沒有則安裝nuget包:Grpc.Core和Google.Protobuf(此次測試沒有安裝)
TestServer服務(wù)端
using GrpcLink; using System; using System.Threading; namespace TestServer { /// <summary> /// 測試服務(wù)端 /// </summary> internal class Program { static void Main(string[] args) { LinkFunc.LinkServerStart("127.0.0.1",9008); Thread.Sleep(500); LinkFunc.ReplyMes = ReplyMes; Console.ReadKey(); } /// <summary> /// 接收到客戶端信息后回復(fù) /// </summary> /// <param name="strRequest">客戶端發(fā)送過來的內(nèi)容</param> /// <returns></returns> public static string ReplyMes(string strRequest) { Console.WriteLine("接收到:" + strRequest); switch (strRequest) { case "1": return "Server識別到1"; case "2": return "Server識別到2"; case "測試": return "開始測試"; case "連接服務(wù)端": return "true"; } return "Server未識別到指定參數(shù)"; } } }
TestCilent客戶端
using GrpcLink; using System; using System.Threading; namespace TestCilent { internal class Program { static void Main(string[] args) { Thread.Sleep(2000); LinkFunc.LinkClientStart("127.0.0.1:9008"); Console.WriteLine("連接服務(wù)端中"); string conn = LinkFunc.SendMes("連接服務(wù)端"); if (conn.Equals("true")) { Console.WriteLine("連接服務(wù)端成功!"); for (int i = 0 ; i < 10 ; i++) { Thread.Sleep(1000); Console.WriteLine("輸入測試內(nèi)容.."); var line = Console.ReadLine(); var ret = LinkFunc.SendMes(line); //獲取到服務(wù)端返回的值 Console.WriteLine(ret); } } Console.WriteLine("連接失敗 , 即將退出"); Thread.Sleep(2000); } } }
測試圖例
以上就是C#中使用gRPC通訊的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于C# gRPC通訊的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C# Socket編程實現(xiàn)簡單的局域網(wǎng)聊天器的示例代碼
這篇文章主要介紹了C# Socket編程實現(xiàn)簡單的局域網(wǎng)聊天器,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03C#自定義鼠標(biāo)拖拽Drag&Drop效果之基本原理及基本實現(xiàn)代碼
拖拽效果無論是在系統(tǒng)上、應(yīng)用上、還是在網(wǎng)頁上,拖拽隨處可見,下面通過本文介紹下C#自定義鼠標(biāo)拖拽Drag&Drop效果之基本原理及基本實現(xiàn)代碼,需要的朋友可以參考下2022-04-04C#使用CefSharp和網(wǎng)頁進(jìn)行自動化交互的示例代碼
CefSharp 是一個用 C# 編寫的開源庫,它封裝了 Google Chrome 瀏覽器的 Chromium 內(nèi)核,CefSharp 允許開發(fā)者在其應(yīng)用程序中嵌入瀏覽器功能,從而能夠展示網(wǎng)頁內(nèi)容、執(zhí)行JavaScript代碼,本文給大家介紹了C#使用CefSharp和網(wǎng)頁進(jìn)行自動化交互,需要的朋友可以參考下2024-07-07