概述
很少写博客,文笔也不太好,难免会存在各种问题,但是我希望能够给这个平台做一点儿个人的分享,本篇文章协作来源于实际项目需求,我国内互联网中未找到能实现的案例及处理解决方案;但是通过翻阅Stackoverflow,有了解决的办法,故此也分享给需要的程序员。
准备工作,使用的vs版本是2019,其中服务端平台是.Net Core,客户端是.Net Framwork
一、服务端项目:创建Asp.net core grpc项目,如图:
找到目标模板,然后选择项目存储位置后,直接下一步,默认框架版本是.net core 3.1版本,然后完成创建。
项目结构:,我们可以看到模板中自动为我们创建了后缀.proto协议文件和GreeterService.cs类文件,这为我们省了很多事情,所以我们可以直接进入客户端了。
二、客户端项目创建及配置:
1.、在vs2019中创建.Net Standard(.Net framwork)控制台,创建完成后,复制服务端的"greet.proto"协议文件到客户端,同时配置客户端控制台项目的.csproj文件,加入如下代码:
<ItemGroup>
<Protobuf Include="greet.proto" GrpcServices="Client" />
</ItemGroup>
2、注意,文件名称和文件存放位置,如:存放在上一级目录,就可以Includ="xxxxx.proto";
3、安装相应的Nuget管理包:Grpc.Tools,Google.Protobuf,以及Grpc.Net.Client或者(Grpc.core,这个包目前进入维护,但是不提供更新了,微软和Grpc团队合作开发了Grpc.Net.Client),然后重新编译生成项目,进入客户端代码编写。
4.客户端代码:注意这里代码,引用的插件是:Grpc.Net.Client,
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(new HelloRequest { Name = "三鲜" });
Console.WriteLine("来自" + reply.Message);
channel.ShutdownAsync().Wait();
Console.WriteLine("任意键退出...");
Console.ReadKey();
5.联调,先启动服务端项目,后启动客户端项目,看效果,如图:
大概的意思是,因为服务端.net core 是http2,那么客户端需要配置http2请求,或者是用grpc-web发送请求,于是,开始增加grpc-web的Nuget包,重新测试,依旧是报错。
6、尝试了修改客户端,设置http2,以及服务端监听5001端口,如下代码,依旧是没用。
//客户端
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
//服务端,在启动类,Program中CreateHostBuilder函数中增加端口监听
webBuilder.ConfigureKestrel(options =>
{
options.AddServerHeader = false;
options.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
//dlistenOptions.UseHttps(certificates);
listenOptions.Protocols = HttpProtocols.Http2;
});
});
7、其它尝试:https://docs.microsoft.com/zh-cn/aspnet/core/grpc/netstandard?view=aspnetcore-5.0,告诉我的理由是System.Net.Http.WinHttpHandler
和win10版本不够。
8、使用自定义证书,打通成功,具体客户端代码和服务端代码:
//客户端
//server.pem 通过pwoershell创建的证书,然后通过openssl生成.pem文件
SslCredentials secureCredentials = new SslCredentials(File.ReadAllText("server.pem"));
var channel = new Channel("localhost", 5001, secureCredentials);
Console.WriteLine("链接完成");
var client = new Greeter.GreeterClient(channel);
Console.WriteLine("连接服务器");
var reply = await client.SayHelloAsync(new HelloRequest { Name = "三鲜" });
Console.WriteLine("来自" + reply.Message);
channel.ShutdownAsync().Wait();
Console.WriteLine("任意键退出...");
Console.ReadKey();
//服务端:启动类,Program类中Main函数
public static void Main(string[] args)
{
//加载证书配置文件,
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddEnvironmentVariables()
.AddJsonFile("Certificate.json", optional: true, reloadOnChange: true)
.AddJsonFile($"certificate.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json",optional:true,reloadOnChange:true)
.Build();
//读取配置文件中的节点下内容
var certificateSettings = config.GetSection("certificateSettings");
string certificateFileName = certificateSettings.GetValue<string>("fileName");
string certificatePassword = certificateSettings.GetValue<string>("password");
//提取私钥,验证客户端的请求,确保是安全的,可靠的请求
var certificates = new X509Certificate2(certificateFileName, certificatePassword);
var host = new WebHostBuilder().UseKestrel(options =>
{
options.AddServerHeader = false;
options.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
//这里很重要,它监控着5001端口的请求是否是安全的,携带公钥的
listenOptions.UseHttps(certificates);
listenOptions.Protocols = HttpProtocols.Http2;
});
})
.UseConfiguration(config)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseUrls("http://localhost:5001")
.Build();
host.Run();
//CreateHostBuilder(args).Build().Run();
}
补充,服务端需要增加证书源文件和证书配置.json,如图:
Certificate.json配置
pwoershell生成证书,源代码:
//中文的地方改成你的需要的
//生成后的证书位置c:tmp
# setup certificate properties including the commonName (DNSName) property for Chrome 58+
$certificate = New-SelfSignedCertificate `
-Subject 改成自己想要的标题不要带乱七八糟的符号(安装证书的时候会显示这个)`
-DnsName 友好域名(例如:localhost) `
-KeyAlgorithm RSA `
-KeyLength 2048 `
-NotBefore (Get-Date) `
-NotAfter (Get-Date).AddYears(2) `
-CertStoreLocation "cert:CurrentUserMy" `
-FriendlyName "证书的友好名称,在IIS指定的时候显示Certificate for .NET Core(Localhost Certificate for .Net Core)" `
-HashAlgorithm SHA256 `
-KeyUsage DigitalSignature, KeyEncipherment, DataEncipherment `
-TextExtension @( "2.5.29.37={text}1.3.6.1.5.5.7.3.1" )
$certificatePath = 'Cert:CurrentUserMy' + ($certificate.ThumbPrint)
# create temporary certificate path
$tmpPath = "C:tmp"
If(!(test-path $tmpPath))
{
New-Item -ItemType Directory -Force -Path $tmpPath
}
# set certificate password here
$pfxPassword = ConvertTo-SecureString -String "你的证书的密码" -Force -AsPlainText
$pfxFilePath = "c:tmp你的证书的名称.pfx"
$cerFilePath = "c:tmp你的证书的名称.cer"
# create pfx certificate
Export-PfxCertificate -Cert $certificatePath -FilePath $pfxFilePath -Password $pfxPassword
Export-Certificate -Cert $certificatePath -FilePath $cerFilePath
# import the pfx certificate
Import-PfxCertificate -FilePath $pfxFilePath Cert:LocalMachineMy -Password $pfxPassword -Exportable
# trust the certificate by importing the pfx certificate into your trusted root
Import-Certificate -FilePath $cerFilePath -CertStoreLocation Cert:CurrentUserRoot
# optionally delete the physical certificates (don’t delete the pfx file as you need to copy this to your app directory)
# Remove-Item $pfxFilePath
Remove-Item $cerFilePath
9、重新编译服务端和客户端的代码,先运行服务端,然后再运行客户端,题外话:第一次不知道为什么,服务端有接受到请求,但是客户端并没有收到返回,于是决定第二天尝试,后来想想可能是openssl窗口影响了,第二天尝试,就成功了,如图:
最后
以上就是简单枫叶为你收集整理的.Net Framwork与.Net core进行gRPC通信的全部内容,希望文章能够帮你解决.Net Framwork与.Net core进行gRPC通信所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复