C# 搭建GRPC,实现双向通信

本文详细介绍了如何在C#中新建GRPC项目,定义服务接口,创建.proto文件,生成代码并实现CorrespondServiceServer。涉及服务定义、方法实现、代码生成工具的使用以及客户端和服务端交互的详细步骤。

一、新建项目,定义GRPC服务接口

vs新建dll项目,项目中NuGet程序包添加Grpc相关引用

定义服务,创建.proto文件

创建文件CorrespondService.proto

syntax = "proto3";
package My.Public;
service CorrespondGrpcService {
  rpc SendMsg(GrpcData) returns (GrpcResult);
  rpc ReceiveDataFromServer(GrpcData) returns (stream GrpcData);
}

message GrpcData {
  string Ip = 1;
  int32 Port = 2;
  string DataId = 3;
  int32 DataPriority = 4;
  string DataType = 5;
  string Conntent = 6;
  string NodeName = 7;
}

message GrpcResult{
	bool result = 1;
}

定义两个服务方法:

客户端发送数据到服务端:SendMsg

服务端发送数据到客户端(从服务端接收数据):ReceiveDataFromServer,因为是服务端主动触发,所以从服务端的返回数据定义成stream形式,流式传输,客户端启动一次该方法,即可等待服务端流式数据发送到客户端。

二、生成代码,添加到项目中

在添加的引用package下找到Grpc.Tool下的文件\tools\windows_x64

使用文件夹中的工具生成文件,到packages的上一层目录框输入cmd回车打开命令提示符窗口

运行命令:packages\Grpc.Tools.2.24.0\tools\windows_x64\protoc.exe -ISystemPublic --csharp_out SystemPublic SystemPublic\PublicClass\Grpc\GrpcService\CorrespondService.proto --grpc_out SystemPublic --plugin=protoc-gen-grpc=packages\Grpc.Tools.2.24.0\tools\windows_x64\grpc_csharp_plugin.exe

 注意自己引用包的版本号和目录路径。 

生成文件后拷贝到相应的目录下,添加到项目中。

三、 服务接口实现:

创建通信服务类CorrespondServiceServer.cs继承CorrespondGrpcService.CorrespondGrpcServiceBase,并实现定义的方法:

    /// <summary>
    /// Grpc服务
    /// </summary>
    public class CorrespondServiceServer : CorrespondGrpcService.CorrespondGrpcServiceBase
    {
        public ConcurrentDictionary<string, TaskInfo> _receiveDataTaskId = new ConcurrentDictionary<string, TaskInfo>();
        public Func<GrpcData, GrpcResult> MessageHandler { get; set; } = null;

        public override Task<GrpcResult> SendMsg(GrpcData request, ServerCallContext context)
        {
            if (MessageHandler == null)
            {
                return Task.FromResult<GrpcResult>(new GrpcResult() { Result = false });
            }
            Tuple<string, int> clientIP = SplitKeyStrGrpcContextPeer(context.Peer);

            if (string.IsNullOrEmpty(request.Ip))
            {
                request.Ip = clientIP.Item1;
                request.Port = clientIP.Item2;
            }
            GrpcResult result = MessageHandler(request);
            return Task.FromResult<GrpcResult>(result);
        }

        public override Task ReceiveDataFromServer(GrpcData request, IServerStreamWriter<GrpcData> responseStream, ServerCallContext context)
        {
            Tuple<string, int> clientIP = SplitKeyStrGrpcContextPeer(context.Peer);
            string IPkeyStr = GetKeyStr(clientIP.Item1, clientIP.Item2);
            if (_receiveDataTaskId.ContainsKey(IPkeyStr))
            {
                // 线程未完成
                if (_receiveDataTaskId[IPkeyStr].IsStarted)
                {
                    bool res = _receiveDataTaskId[IPkeyStr].Stop();
                }

                TaskInfo tmp;
                _receiveDataTaskId.TryRemove(IPkeyStr, out tmp);
            }

            if (!DataQueues.SendDataQueue.ContainsKey(IPkeyStr))
         
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值