当前位置: 首页 > article >正文

C# 中使用 gRPC 通讯

gRPC 是一种高性能、开源的远程过程调用(RPC)框架,支持多种编程语言。本文将介绍如何在 C# 中使用 gRPC 进行通讯,包括创建 gRPC 服务文件、封装服务端和客户端类库,以及进行简单的测试。

参考 : C#封装GRPC类库及调用简单实例 - wtc87 - 博客园 (cnblogs.com)

创建并生成 gRPC 服务文件

  1. 首先,创建一个新的控制台应用程序项目,命名为 MgRPC​。

  2. 在项目中安装以下 NuGet 包:

    • Google.Protobuf
    • Grpc.Core
    • Grpc.Tools

定义 Protocol Buffer 文件

在项目中添加一个新的类文件,命名为 Link.proto​,并清空其内容。然后添加以下代码:


syntax = "proto3";

// 指定了生成的 C# 代码的命名空间为 LinkService。当使用 protobuf 编译器 (protoc) 将这个 .proto 文件转换为 C# 代码时,生成的类将位于 LinkService 命名空间中
option csharp_namespace = "LinkService";

//定义了一个名为 Link 的 gRPC 服务。在 gRPC 中,服务是由一个或多个 RPC 方法组成的
service Link
{
	//定义了一个 RPC 方法。这个方法名为 GetMessage,它接受一个 Mes 类型的消息作为参数,
	//并返回一个 Mes 类型的消息。在 gRPC 中,客户端可以调用这个方法,并发送一个 Mes 消息给服务端,然后服务端会处理这个消息并返回一个 Mes 消息给客户端。
	rpc GetMessage(Mes) returns (Mes);
}

//定义了一个名为 Mes 的消息类型。在 protobuf 中,消息是由一系列字段组成的,每个字段都有一个名称、一个类型和一个标识符。
message Mes
{
    // 客户端发送
	// 定义了一个名为 StrRequest 的字段,类型为 string,标识符为 1。这个标识符在消息内部是唯一的,并且一旦分配就不能更改,因为它被用于序列化和反序列化过程中的字段识别。
	string StrRequest = 1;
	// 同样定义了一个名为 StrReply 的字段,类型为 string,标识符为 2。(服务端回复)
	string StrReply = 2;
}

设置 Link.proto 文件属性

右键点击 Link.proto​ 文件,选择属性,将“生成操作”设置为 Protobuf compiler​。

image

生成 C# 代码

生成解决方案后,会在项目目录下生成 Link.cs​ 和 LinkGrpc.cs​ 两个文件。

image

服务端和客户端类库的封装

  1. 创建一个新的类库项目,命名为 GrpcLink​。
  2. 项目添加现有项,将生成的 Link.cs​ 和 LinkGrpc.cs​ 文件添加到项目中,并安装 Grpc.Core​ 和 Google.Protobuf​ NuGet 包。
  3. 创建两个类:LinkFunc用于放此类库可用于外部引用调用的方法。LinkServerFunc基于Link.LinkBase,用于重写在proto文件中定义的方法。

对于不同的项目,在客户端请求时,服务端要根据自身情况回复想回的内容,因此可以提供一个委托供外部自行开发回复函数。

在LinkFunc类中定义如下:

public static Func<string, string> ReplyMes;

创建服务端和客户端类

在项目中创建两个类:LinkFunc​ 和 LinkServerFunc​。

LinkServerFunc 类
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>
        /// 用于服务端回复委托
        /// </summary>
        public static Func<string,string> ReplyMes;

        // 定义服务端和客户端
        public static Server LinkServer;
        public static LinkClient LinkClient;

        /// <summary>
        ///  服务端启动
        /// </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>
        ///  服务端关闭
        /// </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>
        /// 客户端发送消息函数
        /// </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​ 目录下生成 GrpcLink.dll​ 文件,其他项目可以引用该文件。

创建服务端和客户端调用测试

  1. 创建两个控制台应用程序项目,分别命名为 TestServer​ 和 TestClient​。
  2. GrpcLink.dll​ 文件分别添加到两个项目中,并添加引用。

TestServer 服务端

using GrpcLink;
using System;
using System.Threading;

namespace TestServer
{
    /// <summary>
    /// 测试服务端
    /// </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>
        /// 接收到客户端信息后回复
        /// </summary>
        /// <param name="strRequest">客户端发送过来的内容</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 "连接服务端":
                return "true";
            }
            return "Server未识别到指定参数";
        }
    }
}

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("连接服务端中");
            string conn = LinkFunc.SendMes("连接服务端");

            if (conn.Equals("true"))
            {
                Console.WriteLine("连接服务端成功!");


                for (int i = 0 ; i < 10 ; i++)
                {
                    Thread.Sleep(1000);
                    Console.WriteLine("输入测试内容..");
                    var line = Console.ReadLine();
                    var ret = LinkFunc.SendMes(line);
                    //获取到服务端返回的值
                    Console.WriteLine(ret);

                }
            }

            Console.WriteLine("连接失败 , 即将退出");
            Thread.Sleep(2000);
        }
    }
}

测试图例

image


http://www.kler.cn/a/514252.html

相关文章:

  • PyQt5 超详细入门级教程上篇
  • 【C++】在线五子棋对战项目网页版
  • 数据结构-二叉树
  • HarmonyOS NEXT:华为分享-碰一碰开发分享
  • kafka学习笔记7 性能测试 —— 筑梦之路
  • 写作利器:如何用 PicGo + GitHub 图床提高创作效率
  • linux配置bond学习
  • 2025年PHP面试宝典,技术总结。
  • HTML<bdo>标签
  • 迅为RK3568开发板篇OpenHarmony实操HDF驱动控制LED-接口函数
  • RHCE实验详解
  • 电梯系统的UML文档07
  • centos9编译安装opensips 二【进阶篇-定制目录+模块】推荐
  • react19新API之use()用法总结
  • 【深度学习入门】深度学习知识点总结
  • AutoDev Composer:您身边的 Intellij 平台 Cursor、WinSurf 平替方案(预览版)
  • 项目开发实践——基于SpringBoot+Vue3实现的在线考试系统(八)
  • redis 分布式方案
  • 介绍下常用的前端框架及时优缺点
  • Assembly语言的物联网
  • Java设计模式 八 适配器模式 (Adapter Pattern)
  • ROS2测试仿真
  • 开源视频生成 Pyramid Flow 本地部署实测
  • AI 新动态:技术突破与应用拓展
  • Python爬虫与1688商品详情API接口:开启数据获取新境界
  • 【排查案例】无认证集群空白分区创建元凶排查记录