gRpc NET Core
NET Core下使用gRpc公开服务(SSL/TLS)
一、前言
前一阵子关于.NET的各大公众号都发表了关于gRpc的消息,而随之而来的就是一波关于.NET Core下如何使用的教程,但是在这众多的教程中基本都是泛泛而谈,难以实际在实际环境中使用,而该篇教程以gRpc为主,但是使用了其SSL/TLS,这样更加符合实际的生产使用,期间也会配套的讲解Docker、openssl等。
二、服务端
a.准备工作
笔者的项目分为三个部分分别如下所示:
Sino.GrpcService.Host(控制台):宿主程序
Sino.GrpcService.Impl(类库):实现协议
Sino.GrpcService.Protocol(类库):生成协议
最终的项目如下图所示:

每个项目的project.json如下所示:
其中“buildOptions”和“publishOptions”中我们将后面我们需要的证书包含到输出和发布中,其中我们还利用了“Configuration”相关组件去读取配置信息。
Sino.GrpcService.Impl:
其中我们安装了“MongoDb.Driver”,为了能够贴近真实的情况,笔者这里采用MongoDb作为数据源来提供数据,当然读者为了能够快速上手可以硬编码一些数据。
Sino.GrpcService.Protocol:
至此项目的初始化结束。
b.编写协议
首先我们打开Sino.GrpcService.Protocol项目,在其中新建一个msg.proto文件,打开msg.proto文件,我们将在其中编写基于proto3语言的协议,以便后面自动生成到各语言,如果读者需要更深入的学习可以打开该网站Proto3语言指南。
这里我们定义我们当前使用的是proto3语言并且包名(生成为C#则为命名空间)为:
syntax = "proto3";
package Sino.GrpcService;
笔者为该服务定义了1个服务,且有4种方法:

service MsgService{
rpc GetList(GetMsgListRequest) returns (GetMsgListReply){}
rpc GetOne(GetMsgOneRequest) returns (GetMsgOneReply){}
rpc Edit(EditMsgRequest) returns (EditMsgReply){}
rpc Remove(RemoveMsgRequest) returns (RemoveMsgReply){}
}

对应到其中每个方法的接收参数和返回参数的定义如下:
到这为止我们就完成了协议的编写。
c.将协议生成为C#代码
相对于网站的很多关于C#使用gRpc的教程都是基于.NET项目框架下的,所以可以安装gRpc.Tools,但是.NET Core安装后是找不到工具的,所以读者可以新建一个.NET项目安装该类库,然后将其中的工具复制到Sino.GrpcService.Protocol中,这里读者需要根据你当前的系统去选择,复制完成之后在该项目中新建一个名为“ProtocGenerate.cmd”的文件,在其中输入以下指令:
protoc -I . --csharp_out . --grpc_out . --plugin=protoc-gen-grpc=grpc_csharp_plugin.exe msg.proto
然后读者直接双击运行,就会看到项目下生成了“Msg.cs”和“MsgGrpc.cs”两个文件,这样就完成了所有协议部分的工作了,最终的项目结构如下所示:

d.编写实现代码
有了协议层之后我们就可以开始编写实现了,因为笔者这里使用了MongoDb提供数据所以下文篇幅会较长。
首先打开Sino.GrpcService.Impl项目在其中新建Model文件,然后在该文件夹下新建MsgDM.cs文件,该文件主要是定义MongoDb存储的数据结构,具体内容如下所示:
紧接着我们新建Repositories文件夹,在其中新建四个文件分别为“IDataContext.cs”、“DataContext.cs”、“IMsgRepository.cs”和“MsgRepository.cs”。打开IDataContext.cs文件在其中编写如下内容:

/// <summary>
/// 数据库上下文
/// </summary>
public interface IDataContext
{
IMongoDatabase Database { get; set; }
}

打开DataContext.cs文件进行数据库初始化相关工作:

public class DataContext : IDataContext
{
public IMongoDatabase Database { get; set; } public DataContext(IConfigurationRoot config)
{
var client = new MongoClient(config.GetConnectionString("mongodb"));
Database = client.GetDatabase("aSQ0cWkEshl8NiVn");
}
}

打开IMsgRepository.cs,我们需要在其中定义仓储提供的操作:

/// <summary>
/// 消息仓储
/// </summary>
public interface IMsgRepository
{
/// <summary>
/// 获取列表
/// </summary>
Task<List<MsgDM>> GetList(long userId, string title, long startTime, long endTime); /// <summary>
/// 获取实体
/// </summary>
Task<MsgDM> Get(string id); /// <summary>
/// 更新实体
/// </summary>
Task<bool> Update(MsgDM data); /// <summary>
/// 添加实体
/// </summary>
Task<string> Insert(MsgDM data); /// <summary>
/// 删除实体
/// </summary>
Task<bool> Delete(string id);
}

对应的我们还需要打开MsgRepository.cs文件实现该接口:
完成了上面关于数据库的工作,下面我们就进入正题,开始实现gRpc服务了,首先我们在项目根目录下新建MsgServiceImpl.cs文件,在其中实现我们协议中的服务:
三、证书生成
a.安装openssl
首先读者需要从该网站下载openssl安装程序:
笔者的系统是Win10 64所以下载的是“Win64 OpenSSL v1.1.0b”。
b.制作证书
网上有很多的教程,但是对于新手来说直接给绕晕了,有的有ca、client和service有的没有,这里笔者提供一个全面的cmd脚本(默认CA是自己):

1 @echo off
2 set OPENSSL_CONF=c:\OpenSSL-Win64\bin\openssl.cfg
3
4 echo Generate CA key:
5 openssl genrsa -passout pass:1111 -des3 -out ca.key 4096
6
7 echo Generate CA certificate:
8 openssl req -passin pass:1111 -new -x509 -days 365 -key ca.key -out ca.crt -subj "/C=CN/ST=JS/L=ZJ/O=sino/OU=test/CN=root"
9
10 echo Generate server key:
11 openssl genrsa -passout pass:1111 -des3 -out server.key 4096
12
13 echo Generate server signing request:
14 openssl req -passin pass:1111 -new -key server.key -out server.csr -subj "/C=CN/ST=JS/L=ZJ/O=sino/OU=test/CN=root"
15
16 echo Self-sign server certificate:
17 openssl x509 -req -passin pass:1111 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
18
19 echo Remove passphrase from server key:
20 openssl rsa -passin pass:1111 -in server.key -out server.key
21
22 echo Generate client key
23 openssl genrsa -passout pass:1111 -des3 -out client.key 4096
24
25 echo Generate client signing request:
26 openssl req -passin pass:1111 -new -key client.key -out client.csr -subj "/C=CN/ST=JS/L=ZJ/O=sino/OU=test/CN=root"
27
28 echo Self-sign client certificate:
29 openssl x509 -passin pass:1111 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
30
31 echo Remove passphrase from client key:
32 openssl rsa -passin pass:1111 -in client.key -out client.key

以上的脚本也会生成我们下面Demo中使用的证书。
四、完善服务端
用了上面的证书之后我们需要继续把服务端启动gRpc服务部分的代码书写完毕,这里笔者是采用命令行形式运行的,所以gRpc的启动是独立放在一个文件文件中,如下RpcConfiguration所示:
其中我们使用了server.crt和server.key这两个证书,所以在Host项目中需要将这个两个证书文件copy到项目根目录下,如果需要发布的时候包含则需要在project.json中配置如下节:
"publishOptions": {
"include": [ "server.crt", "server.key", "appSettings.json", "appSettings.*.json" ]
}
最后我们需要在Program中启动对应的gRpc即可。
五、客户端编写
完成了服务端的编写剩下的就是客户端的编写,当然客户端的编写相对容易很多,笔者这里直接把Sino.GrpcService.Protocol项目包含到客户端解决方案中了(在正式开发中建议采用nuget包进行管理),为了简单起见,所以只调用了其中一个服务接口:

public static class MsgServiceClient
{
private static Channel _channel;
private static MsgService.MsgServiceClient _client; static MsgServiceClient()
{
var cacert = File.ReadAllText("server.crt");
var ssl = new SslCredentials(cacert);
var channOptions = new List<ChannelOption>
{
new ChannelOption(ChannelOptions.SslTargetNameOverride,"root")
};
_channel = new Channel("grpcservice.t0.daoapp.io:61130", ssl, channOptions);
_client = new MsgService.MsgServiceClient(_channel);
} public static GetMsgListReply GetList(int userId, string title, long startTime, long endTime)
{
return _client.GetList(new GetMsgListRequest
{
UserId = userId,
Title = title,
StartTime = startTime,
EndTime = endTime
});
}
}

需要注意下其中“ChannelOptions.SslTargetNameOverride”这部分是必须的,因为我们是自己生成的证书,所以域名是root,如果是生产环境可以不需要。
六、利用Docker运行
a.安装Docker For Windows
这里需要win10的系统,这样可以直接在ps中直接利用docker指令了。
b.编写Dockerfile
因为1.1版本出来了,但是经过本人的验证,如果你的应用不升级是无法使用该镜像的,默认使用1.1,所以这里我们的Dockerfile需要指定下特定的版本,否则是无法构建的,我们首先在解决方案的根目录下新建Dockerfile文件,然后在其中放入以下命令:

1 FROM microsoft/dotnet:1.0-sdk-projectjson
2
3 ADD ./ /usr/local/src
4 WORKDIR /usr/local/src/Sino.GrpcService.Host/
5
6 RUN cd /usr/local/src/
7 RUN dotnet restore -v http://api.nuget.org/v3/index.json
8 RUN dotnet build
9
10 EXPOSE 9007
11
12 CMD ["dotnet","run"]

c.生成镜像并运行
我们打开ps,然后cd到解决方案的文件夹下利用:
docker build -t gRpcService:1.0 .
开始构建,基于国内的情况建议大家将docker默认拉取镜像的地址调整下。生成好之后,利用以下指令去启动即可:
docker run -d –name -p 9007:9007 gRpcService gRpcService:1.0
当然客户端连接的地址和端口也要根据-p指定的情况去调整。
七、其他
对应的源码可以访问以下地址:
https://github.com/Vip56/Sino.GrpcService
https://github.com/Vip56/Sino.GrpcClient
如果需要询问相关问题的可以短消息给我。
gRpc NET Core的更多相关文章
- gRPC .NET Core跨平台学习
前些天发布gRPC C# 学习,在.NET Framework 中使用gRPC ,今天来学习 .NET Core gRPC. gRPC 的.NET Core 包在NuGet 上发布了,结合.NET C ...
- 谷歌发布的首款基于HTTP/2和protobuf的RPC框架:GRPC
Google 刚刚开源了grpc, 一个基于HTTP2 和 Protobuf 的高性能.开源.通用的RPC框架.Protobuf 本身虽然提供了RPC 的定义语法,但是一直以来,Google 只开 ...
- .net core 用grpc实现微服务
GRPC 是Google发布的一个开源.高性能.通用RPC(Remote Procedure Call)框架.提供跨语言.跨平台支持.以下以.NET Core 使用控制台.docker中演示如何使用G ...
- .NET Core下使用gRpc公开服务(SSL/TLS)
一.前言 前一阵子关于.NET的各大公众号都发表了关于gRpc的消息,而随之而来的就是一波关于.NET Core下如何使用的教程,但是在这众多的教程中基本都是泛泛而谈,难以实际在实际环境中使用,而该篇 ...
- asp.net core 3.0 gRPC框架小试
什么是gRPC gRPC是google开源的一个高性能.跨语言的RPC框架,基于HTTP2协议,采用ProtoBuf 定义的IDL. gRPC 的主要优点是: 现代高性能轻量级 RPC 框架. 协定优 ...
- ASP.NET Core 3.0 上的gRPC服务模板初体验(多图)
早就听说ASP.NET Core 3.0中引入了gRPC的服务模板,正好趁着家里电脑刚做了新系统,然后装了VS2019的功夫来体验一把.同时记录体验的过程.如果你也想按照本文的步骤体验的话,那你得先安 ...
- .net core 3.0中可以使用gRPC了
今天发现.net core下有gRPC模板了,这个可是补全了.net core下高性能RPC框架缺失这一大短板了. 使用模板创建了工程后,发现连客户端的示例也创建了. 更加给力的是,IDE是能直接识别 ...
- .net core grpc 实现通信(一)
现在系统都服务化,.net core 实现服务化的方式有很多,我们通过grpc实现客户端.服务端通信. grpc(https://grpc.io/)是google发布的一个开源.高性能.通用RPC(R ...
- .net core grpc consul 实现服务注册 服务发现 负载均衡(二)
在上一篇 .net core grpc 实现通信(一) 中,我们实现的grpc通信在.net core中的可行性,但要在微服务中真正使用,还缺少 服务注册,服务发现及负载均衡等,本篇我们将在 .net ...
随机推荐
- 在Window 下安装Redis数据库
小Alan国庆后就要回深圳找工作了,最近在复习工作所需的相关的技术,今天刚好复习到redis,redis是一个非关系型(NoSql)数据库,采用key-value的方式存储数据,她可以保存字符串(St ...
- PHP延迟静态绑定 static关键字
示例代码1 abstract class Parent { } class Man extends Parent { public static function create(){ return n ...
- Apache的Order Allow,Deny 详解
Allow和Deny可以用于apache的conf文件或者.htaccess文件中(配合Directory, Location, Files等),用来控制目录和文件的访问授权. 所以,最常用的是: O ...
- HBase应用开发回顾与总结系列之三:RowKey行键生成器工具
所谓RowKey行键生成器,是指通过软件工具制定行键生成策略,并可将策略信息保存成本地策略文件,待需要时再将本地策略文件序列化成行键生成策略对象,传入数据行信息后可自动生成RowKey行键. 那么 ...
- Equinox P2的学习
product.configuration 点击“Add按钮”并添加以下插件: org.eclipse.equinox.p2.ui org.eclipse.equinox.p2.ui.sdk org. ...
- 理解 Linux 网络栈(3):QEMU/KVM + VxLAN 环境下的 Segmentation Offloading 技术(发送端)
本系列文章总结 Linux 网络栈,包括: (1)Linux 网络协议栈总结 (2)非虚拟化Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO (3)QEMU/KVM + Vx ...
- Java入门(二)——果然断更的都是要受惩罚的。。。
断更了一个多月,阅读量立马从100+跌落至10-,虽说不是很看重这个,毕竟只是当这个是自己的学习笔记,但有人看,有人评论,有人认同和批评的感觉还是很巴适的,尤其以前有过却又被剥夺的,惨兮兮的. 好好写 ...
- java设计模式之命令模式
学校中.生活中.社会中总是会存在一定的阶层,虽然我们很多人都不可认可阶层的存在.命令这一词也就在阶层中诞生.家长命令孩子,老师命令学生,领导命令小娄娄.这些都在我们的生活存在的东西,相信这一个模式学习 ...
- 认识与入门 Markdown,Markdown教程
一.认识 Markdown 在刚才的导语里提到,Markdown 是一种用来写作的轻量级「标记语言」,它用简洁的语法代替排版,而不像一般我们用的字处理软件 Word 或 Pages 有大量的排版.字体 ...
- 校园导游系统(C++实现,VC6.0编译,使用EasyX图形库)
运行效果: 说明: 由于当年还不会使用多线程,所以很多获取用户点击的地方都是使用循环实现的...CPU占用率会比较高. 代码: //校园导游系统.cpp 1 #include <graphics ...