C#中使用gRPC通訊的示例詳解
在c#中使用gRPC通訊
參考:C#封裝GRPC類庫及調(diào)用簡單實(shí)例
包括:GRPC文件的創(chuàng)建生成、服務(wù)端和客戶端函數(shù)類庫的封裝、創(chuàng)建服務(wù)端和客戶端調(diào)用測(cè)試。
創(chuàng)建并生成GRPC服務(wù)文件
- 創(chuàng)建新項(xiàng)目控制臺(tái)應(yīng)用 , 項(xiàng)目名稱(MgRPC)
- 安裝三個(gè)nuget包 Google.Protobuf , Grpc.Core , Grpc.Tools
- 項(xiàng)目添加新建項(xiàng),選擇類,修改名稱為Link.proto,添加后把Link.proto里面內(nèi)容清空
定義Protocol
添加代碼。測(cè)試實(shí)例為服務(wù)端和客戶端傳輸字符串消息,只定義了一個(gè)方法(客戶端調(diào)用,服務(wù)端重寫),傳輸內(nèi)容包括請(qǐng)求字符串和回復(fù)字符串。此處可自行定義。
syntax = "proto3";//proto3 是 Protocol Buffers 的第三個(gè)版本
// 指定了生成的 C# 代碼的命名空間為 LinkService。當(dāng)使用 protobuf 編譯器 (protoc) 將這個(gè) .proto 文件轉(zhuǎn)換為 C# 代碼時(shí),生成的類將位于 LinkService 命名空間中
option csharp_namespace = "LinkService";
//定義了一個(gè)名為 Link 的 gRPC 服務(wù)。在 gRPC 中,服務(wù)是由一個(gè)或多個(gè) RPC 方法組成的
service Link
{
//定義了一個(gè) RPC 方法。這個(gè)方法名為 GetMessage,它接受一個(gè) Mes 類型的消息作為參數(shù),
//并返回一個(gè) Mes 類型的消息。在 gRPC 中,客戶端可以調(diào)用這個(gè)方法,并發(fā)送一個(gè) Mes 消息給服務(wù)端,然后服務(wù)端會(huì)處理這個(gè)消息并返回一個(gè) Mes 消息給客戶端。
rpc GetMessage(Mes) returns (Mes);
}
//定義了一個(gè)名為 Mes 的消息類型。在 protobuf 中,消息是由一系列字段組成的,每個(gè)字段都有一個(gè)名稱、一個(gè)類型和一個(gè)標(biāo)識(shí)符。
message Mes
{
// 客戶端發(fā)送
// 定義了一個(gè)名為 StrRequest 的字段,類型為 string,標(biāo)識(shí)符為 1。這個(gè)標(biāo)識(shí)符在消息內(nèi)部是唯一的,并且一旦分配就不能更改,因?yàn)樗挥糜谛蛄谢头葱蛄谢^程中的字段識(shí)別。
string StrRequest = 1;
// 同樣定義了一個(gè)名為 StrReply 的字段,類型為 string,標(biāo)識(shí)符為 2。(服務(wù)端回復(fù))
string StrReply = 2;
}
設(shè)置Link.proto
右鍵Link.proto文件選擇屬性,生成操作選擇如圖:

生成cs文件代碼
生成解決方案。在下圖路徑得到自動(dòng)生成的兩個(gè)類。

至此,獲得GRPC服務(wù)需要的三個(gè)文件:Link.proto、Link.cs、LinkGrpc.cs??梢詫⑦@三個(gè)文件放在一個(gè)項(xiàng)目中直接使用,需要重寫一下服務(wù)端方法、創(chuàng)建服務(wù)端和客戶端的啟動(dòng)方法。但是如果不同的項(xiàng)目軟件之間通訊需要各自如此開發(fā)??梢韵确庋b成一個(gè)GRPC類庫供其他項(xiàng)目直接調(diào)用。
服務(wù)端和客戶端類庫的封裝
- 創(chuàng)建類庫(.NET Framework)項(xiàng)目 , 項(xiàng)目名稱(GrpcLink)
- 項(xiàng)目添加現(xiàn)有項(xiàng),上面獲得的三個(gè)文件(Link.cs , LinkGrpc.cs)。安裝nuget包:Grpc.Core和Google.Protobuf。
- 創(chuàng)建兩個(gè)類:LinkFunc用于放此類庫可用于外部引用調(diào)用的方法。LinkServerFunc基于Link.LinkBase,用于重寫在proto文件中定義的方法。
對(duì)于不同的項(xiàng)目,在客戶端請(qǐng)求時(shí),服務(wù)端要根據(jù)自身情況回復(fù)想回的內(nèi)容,因此可以提供一個(gè)委托供外部自行開發(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ù)端啟動(dòng)
/// </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>
/// 客戶端啟動(dòng)
/// </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中可以得到項(xiàng)目的dll文件GrpcLink.dll,其他項(xiàng)目可以引用使用了。
創(chuàng)建服務(wù)端和客戶端調(diào)用測(cè)試
- 創(chuàng)建兩個(gè)控制臺(tái)(.NET Framework)項(xiàng)目 , 項(xiàng)目名稱TestCilent , TestServer
- 將上述GrpcLink.dll文件分別放入兩個(gè)項(xiàng)目中,并添加dll引用。 如果沒有則安裝nuget包:Grpc.Core和Google.Protobuf(此次測(cè)試沒有安裝)
TestServer服務(wù)端
using GrpcLink;
using System;
using System.Threading;
namespace TestServer
{
/// <summary>
/// 測(cè)試服務(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識(shí)別到1";
case "2":
return "Server識(shí)別到2";
case "測(cè)試":
return "開始測(cè)試";
case "連接服務(wù)端":
return "true";
}
return "Server未識(shí)別到指定參數(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("輸入測(cè)試內(nèi)容..");
var line = Console.ReadLine();
var ret = LinkFunc.SendMes(line);
//獲取到服務(wù)端返回的值
Console.WriteLine(ret);
}
}
Console.WriteLine("連接失敗 , 即將退出");
Thread.Sleep(2000);
}
}
}測(cè)試圖例

以上就是C#中使用gRPC通訊的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于C# gRPC通訊的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
c# n個(gè)數(shù)排序?qū)崿F(xiàn)代碼
c# n個(gè)數(shù)排序?qū)崿F(xiàn)代2009-07-07
在C#中創(chuàng)建和讀取XML文件的實(shí)現(xiàn)方法
項(xiàng)目中需要將前臺(tái)頁面中的信息保存下來并存儲(chǔ)為xml文件格式到數(shù)據(jù)庫中去。因此我先在這里通過一個(gè)小實(shí)例來學(xué)習(xí)xml的創(chuàng)建與讀取2013-09-09
C#中的XML與JSON數(shù)據(jù)處理的案例詳解
在現(xiàn)代軟件開發(fā)中,數(shù)據(jù)交換和存儲(chǔ)的需求日益增長,而 XML 和 JSON 成為了兩種最常用的數(shù)據(jù)格式,它們各有特點(diǎn),在不同的場景下有著各自的優(yōu)勢(shì),本文將從 C# 的角度出發(fā),探討如何處理這兩種數(shù)據(jù)格式,并分享一些常見的問題及解決方法,需要的朋友可以參考下2024-09-09
C#中把FastReport.Net報(bào)表控件的數(shù)據(jù)保存到數(shù)據(jù)庫
這篇文章介紹了在數(shù)據(jù)庫中保存FastReport.Net報(bào)表的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
通過C#調(diào)用cmd來修改服務(wù)啟動(dòng)類型
可以使用System.ServiceProcess.ServiceController這個(gè)類允許連接到正在運(yùn)行或者已停止的服務(wù)、對(duì)其進(jìn)行操作或獲取有關(guān)它的信息但是這個(gè)類并沒有提供修改服務(wù)啟動(dòng)類型的方法,可以通過C#調(diào)用cmd來修改2012-12-12

