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安装程序:

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.crtserver.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

如果需要询问相关问题的可以短消息给我。

时间: 12-13

gRpc NET Core的相关文章

gRPC之Node Quick Start

在node环境下我们使用一个小例子作为引导: 在开始之前请确认如下: 1.node:版本在0.12以上 下载这个例子 为了更好地开始这个例子,你需要在本地对这个例子代码做一个备份.下载这个例子的代码从我们的GitHub代码仓库(下面的命令克隆整个代码库,但是你却只需要这个例子作为快速的引导以及其他的教程) $ # Clone the repository to get the example code $ git clone -b v1.0.0 https://github.com/grpc/g

.net core 用grpc实现微服务

GRPC?是Google发布的一个开源.高性能.通用RPC(Remote Procedure Call)框架.提供跨语言.跨平台支持.以下以.NET Core 使用控制台.docker中演示如何使用GRPC框架. ? ? 软件版本 .net core :1.0.1 GRPC:1.0.1-pre1 ? ? ? ? 1.定义服务 使用proto3语法定义一个服务,主要测试package.import.常用类型的测试, proto3语法: https://developers.google.com/p

谷歌发布的首款基于HTTP/2和protobuf的RPC框架:GRPC

Google 刚刚开源了grpc,  一个基于HTTP2 和 Protobuf 的高性能.开源.通用的RPC框架.Protobuf 本身虽然提供了RPC  的定义语法,但是一直以来,Google 只开源了Protobuf 序列化反序列化的代码,而没有开源RPC 的实现,于是存在着众多良莠不齐的第三方RPC 实现,不过我在项目中采用WCF搭配Protobuf是一个很不错的RPC实现,Google这个框架是是基于HTTP2的,这是他有特色的地方,带来诸如双向流.流控.头部压缩.单TCP连接上的多复用

gRPC Client的负载均衡器

一.gRPC是什么? gRPC是一个高性能.通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers)序列化协议开发,且支持众多开发语言.gRPC提供了一种简单的方法来精确地定义服务和为iOS.Android和后台支持服务自动生成 可靠性很强的客户端功能库.客户端充分利用高级流和链接功能,从而有助于节省带宽.降低的TCP链接次数.节省CPU使用.和电池寿命. 二.为什么使用gRPC? 有了 gRPC, 我们

C# 使用 grpc 问题汇总

grpc 是个跨平台的远程调用框架,第一次在windows平台使用,有很多问题需要面对,下面做个汇总,以备检查 消息长度设置 出现的问题 1 客户端出现异常 未经处理的异常: Grpc.Core.RpcException: Status(StatusCode=Internal, Detail="Max message size exceeded") 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task

.Net Core + Angular Cli 开发环境搭建

一.基础环境配置 1.安装VS 2017 v15.3或以上版本 2.安装VS Code最新版本 3.安装Node.js v6.9以上版本 4.重置全局npm源,修正为 淘宝的 NPM 镜像: npm install -g cnpm --registry=https://registry.npm.taobao.org 5.安装TypeScript cnpm install -g typescript typings 6.安装 AngularJS CLI cnpm install -g @angul

java.lang.NoSuchMethodError: org.springframework.web.context.ConfigurableWebApplicationContext.getEnvironment()Lorg/springframework/core/env/ConfigurableEnvironment;问题

在springsecurity学习中,在加入spring有关的jar包后,出现java.lang.NoSuchMethodError: org.springframework.web.context.ConfigurableWebApplicationContext.getEnvironment()Lorg/springframework/core/env/ConfigurableEnvironment报错 出错原因:jar包版本有冲突 解决方法:换不同版本的jar包就可以解决问题了

ASP.NET Core中使用默认MVC路由

ASP.NET Core里Route这块的改动不大,只是一些用法上有了调整,提供了一些更加简洁的语法. 而对于自定义路由的支持当然也是没有问题的,这个功能应该是从MVC1.0版本就已经有这个功能. 先看看ASP.NET Core里面实现默认MVC路由的配置方式 通常情况下,在使用MVC项目的时候,默认的路由就足够了,就是常见的通过Controller和Action获取具体的方法的方式. 从一个最基本的项目开始,执行以下步骤,就可以使得项目支持MVC路由 1.创建一个空白的ASP.NET Core

NET Core项目定义Item Template

NET Core项目定义Item Template 作为这个星球上最强大的IDE,Visual Studio不仅仅提供了很多原生的特性,更重要的是它是一个可定制的IDE,比如自定义Project Template和Item Template就是一个非常有用的扩展点.这里我们主要关注Item Template,它时我们可以在"Add new Item"对话框中添加我们自定义的Item(如下图所示).如果不了解Item Template,Scott Gu的文章. 我们之前自定义了一些Ite