新建项目 引入Nuget包
Install-Package Google.Protobuf
Install-Package Grpc
Install-Package Grpc.Tools
Install-Package Grpc.Core
Proto文件格式大致如下,具体自行百度查看
syntax = "proto3";
option csharp_namespace = "GrpcNetService";
package case;
// The greeting service definition.
service Caseer {
// Sends a greeting
rpc SayHello (CaseRequest) returns (CaseReply);
rpc GetCase(CaseRequest) returns (CaseReply);
rpc GetCaseList(CaseRequest) returns (CaseListReply);
rpc GetCaseByID(CaseRequest) returns (CaseInfoReply);
}
message CaseListReply{
repeated CaseDto CaseDto=1;
}
message CaseDto{
string caseID=1;
string caseName=2;
string descriptCon=3;
string major=4;
string createTime=5;
int32 Sex=6;
}
message CaseInfoReply{
string caseInfo=1;
}
// The request message containing the user's name.
message CaseRequest {
string name = 1;
}
// The response message containing the greetings.
message CaseReply {
string message = 1;
}
在项目的找到packages 文件夹 ,下面执行的路径修改为packages的相关路径
packages同级新建gRPCDemo文件夹(用于存放要使用的Proto文件及生成C#代码 文件)
在packages上一级执行cmd ,生成的文件Copy到要使用的项目中
packages\Grpc.Tools.2.50.0\tools\windows_x64\protoc.exe -I gRPCDemo --csharp_out GRPCDemo gRPCDemo\*.proto --grpc_out gRPCDemo --plugin=protoc-gen-grpc=packages\Grpc.Tools.2.50.0\tools\windows_x64\grpc_csharp_plugin.exe
新建服务端及客户端 copy生成的Protocol生成的文件到项目中
在服务端 进行服务接口实现 新建文件夹gRpcService 在该文件夹创建对应的类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Grpc.Core;
using GrpcNetService;
using WPFAppDemo.DBHelper;
namespace WPFAppDemo.gRpcService
{
class CaseService : Caseer.CaseerBase
{
/// <summary>
/// 返回List
/// </summary>
/// <param name="request"></param>
/// <param name="context"></param>
/// <returns></returns>
public override Task<CaseListReply> GetCaseList(CaseRequest request, ServerCallContext context)
{
using (var db = new DataBaseEntities())
{
string strName = string.Empty;
List<CaseDto> caselist = new List<CaseDto>();
var list = db.T_Case.ToList();
foreach (var item in list)
{
caselist.Add(new CaseDto { CaseID = item.ID, CaseName = item.Name, CreateTime = item.CreateTime.ToString(), DescriptCon = item.Describe, Major = item.Major, Sex = item.Sex });
// strName += item.Name + ",";
}
CaseListReply caseListReply = new CaseListReply();
caseListReply.CaseDto.AddRange(caselist);
return Task.FromResult(caseListReply);
}
//return base.GetCaseList(request, context);
}
public override Task<CaseInfoReply> GetCaseByID (CaseRequest request, ServerCallContext context)
{
using (var db = new DataBaseEntities())
{
string strName = string.Empty;
var caseModel = db.T_Case.FirstOrDefault();
strName += caseModel.Name + ","+ caseModel.CreateTime+caseModel.Difficulty+caseModel.Describe;
return Task.FromResult(new CaseInfoReply() { CaseInfo = strName });
}
// return base.GetCaseByID(request, responseStream, context);
}
public override Task<CaseReply> GetCase(CaseRequest request, ServerCallContext context)
{
using (var db = new DataBaseEntities())
{
string strName = string.Empty;
var list = db.T_Case.ToList();
foreach (var item in list)
{
strName += item.Name + ",";
}
return Task.FromResult(new CaseReply() { Message = strName });
}
}
}
}
以上代码中含有链接数据的相关已忽略,为了测试可以做假数据操作即可!
服务端主程序代码如下:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WPFAppDemo.Common;
using WPFAppDemo.DBHelper;
using Grpc.Core;
using WPFAppDemo.gRpcService;
using GrpcNetService;
namespace WPFAppDemo
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private Server server;
public MainWindow()
{
InitializeComponent();
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
server = new Server()
{
Services = { Caseer.BindService(new CaseService()) },
Ports = { new ServerPort("localhost", 8099, ServerCredentials.Insecure) }
};
server.Start();
Console.WriteLine("Service running……");
}
}
}
客户端代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Grpc.Core;
using GrpcNetService;
namespace WPFGRPCClient
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private Channel channel;
private Caseer.CaseerClient client;
public MainWindow()
{
InitializeComponent();
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
try
{
channel = new Channel("localhost", 8099, ChannelCredentials.Insecure);
client = new Caseer.CaseerClient(channel);
var response = client.GetCaseByID(new CaseRequest() { Name = "Link Sun" });
var caseListStr = client.GetCase(new CaseRequest() { });
var caselist=client.GetCaseList(new CaseRequest());
MessageBox.Show(caseListStr+"\r\n"+caselist.ToString());
// lvResponse.Items.Add(response);
Console.WriteLine(response);
}
catch (Exception)
{
throw;
}
}
}
}
启动服务端 客户端查看效果
参照地址 :
Wpf的gRpc的Server/Client - 非法关键字 - 博客园
C#调用gRPC的步骤及详细说明(踩坑后总结)_xulong5000的博客-CSDN博客_c# grpc
C# 搭建GRPC,实现双向通信_glmushroom的博客-CSDN博客_c# grpc
在C#中使用gRPC及protobuf简介_whereismatrix的博客-CSDN博客
七丶google.protobuf的使用以及protobuff的map,list书写_YYyyCCCcccBb的博客-CSDN博客_protobuf list