怎么用asp.net core+gRPC实现旧WCF项目迁移

发布时间:2021-12-06 11:54:39 作者:iii
来源:亿速云 阅读:123

本篇内容主要讲解“怎么用asp.net core+gRPC实现旧WCF项目迁移”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用asp.net core+gRPC实现旧WCF项目迁移”吧!

一个月前,公司的运行WCF的windows服务器down掉了,由于 AWS 没有通知,没有能第一时间发现问题。
所以,客户提出将WCF服务由C#改为JAVA,在Linux上面运行;一方面,AWS对Linux有较多的监控措施,另一方面,假如出现问题,可以设置自动重启等服务。

老旧的WCF服务

目前WCF服务,主要提供windows桌面软件的数据接口,应该有五六年的历史了。我进入公司后,WCF服务的代码,一直由我一个人来维护。存在很多历史遗留问题,也有不同版本的共存。

如果java重写的话,其中的业务逻辑代码,难免会出现各种各样的bug,增加开发和测试的工作量。听说,要移植到linux服务上后,第一时间想到的就是跨平台.net core
.net core 经过了四年的发展,到目前的 3.1 LST版本,已经是非常成熟的跨平台解决方案了。

之后,我就在网上查找,有没有WCF的.net core 版本,查询到的信息总结如下:

  1. Core WCF不打算做WCF到.NET Core的100%兼容的移植;

  2. 对于新应用程序,WCF这种SOAP技术不建议使用;

  3. 对于老的应用程序,建议将这些保留在.NET Framework上;

  4. 如果您真的想将一个旧的应用程序迁移到.NET Core并且想继续使用WCF和WF, 社区的开源项目也是可以的,但是上生产的时间表就要到了2020年.NET 5;

  5. 开源社区,也强烈建议目前不要用于生产环境。

很遗憾,想不改动代码就迁移到 Linux 上面,基本是不可能的了。
我的最理想情况,尽量少的手写代码,最好可以像WCF一样,自动生成代理类,像访问本地代码一样,来调用接口。之后,就发现了asp.net core + gRPC这种形式。

了解gRPC

gRPC 的好处非常多:高性能传输数据小,支持多语言生成工具使用HTTP2协议,这些好处网上都有大量详细的介绍,本文不做赘述。
其实我最看重的部分还是:客户端和服务端代码,都可以通过一个 proto 协议文件来自动生成

而微软官方,也建议用 ASP.NET Core gRPC。《适用于 WCF 开发人员的 ASP.NET Core gRPC》

gRPC 的 proto 文件

为了了解 proto 文件的写法,硬着头皮看谷歌英文文档, proto3 勉强了解大概。《Language Guide (proto3)》,下面列出一些,我在使用过程中的经验总结:

  1. 一个RPC服务必须有且仅有一个入参一个出参;假如不需要的话,可以设置为空的对象google.protobuf.Empty

  2. 基本类型( string, int32 等)不能作为PRC服务的参数,可使用谷歌提供的封装对象,如:google.protobuf.StringValuegoogle.protobuf.Int32Value 详见 google/protobuf/wrappers.proto文件;

  3. proto3 不允许null值,这是由于 Protobuf 二进制序列化,空和null不能区分,利用google.protobuf.StringValue 则可以实现null值;同第2点;

  4. string name=1;这个数字必须写,用作 Protobuf 二进制序列化,并且常用的属性最好放在前12;PS: 太不习惯了,总以为是在赋值操作;

  5. 枚举类型必须从0开始,即:enum Weekday {Sunday=0;Monday=2;}

  6. 时间类型google.protobuf.Timestamp,必须是 UTC 时间;

  7. 消息体 message 不能继承,可多层嵌套,可以导入 import;

// 我的例子
syntax = "proto3";

option csharp_namespace = "GrpcServiceTest.Protos";

import "Protos/ClientInfoModel.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";

package UserManagement;
service UserManagement {
   rpc UserReset(google.protobuf.Empty) returns (google.protobuf.Empty);
   rpc UserLogin(LoginRequestV2) returns(LoginResponseV2);
}

message LoginRequestV2 {
   string UserName = 1;
   string Password = 2;
}

message LoginResponseV2 {
   int32 TAG = 1;
   string Message = 2;
   UserModelV2 UserInfo = 3;

   message UserModelV2 {
       int64 UserID = 1;
       string UserName = 2;
       google.protobuf.StringValue Address = 3;
       google.protobuf.Timestamp LastLoginTime = 4;
       repeated PrivGroupPluginModelV2 PrivGroupPlugins = 5;
       bool IsDeleted = 6;

       message PrivGroupPluginModelV2{
       int64 Id=1;
       google.protobuf.Timestamp CreateDateTime=2;
       google.protobuf.Timestamp ModifyDateTime=3;
       int64 PluginId=4;
       int64 PrivGroupPluginID=5;
       }
   }
}

根据 proto 生成代码

用vs2019,选择gRPC Service项目模板,创建项目。它会自动加上nuget包Grpc.AspNetCore。如果没有的话,则需要自己安装nuget包:Grpc.coreGoogle.ProtobufGrpc.Tools
由 proto 文件生成代码有两种方式:

  1. 通过vs右键 proto文件,选择 属性Property,选择Build Action中的Protobuf complier,会看到 gRPC Stub Classes,有三个选项 Server Only , Clent Only 和 Both 按需选择;
    怎么用asp.net core+gRPC实现旧WCF项目迁移

  2. 编辑项目文件 csproj,编辑 Protobuf 属性,这种方法还可以使用路径宏通配符等,相当方便,强烈推荐

<ItemGroup>
   <Protobuf Include="Protos/*.proto" OutputDir="%(ProjectDir)ServerGrpc" GrpcServices="Server" />
</ItemGroup>

怎么用asp.net core+gRPC实现旧WCF项目迁移

asp.net core 3.1

现在,恰好赶上了net core 3.1的这个 LST版本 ( long-term-support )的发布,而 NET Core 3.0 生命周期终结于 2020年3月3日,下个大一统版本 NET 5 ,正式版本还要等到明年。至于为什么没有 NET 4.0版本,官方解释,为了避免于 .NET Framework 4.X 产生歧义。

一步步的按照官方文档的指引,跟着做就可以了。《使用 ASP.NET Core 的 gRPC 服务》,《教程:在 ASP.NET Core 中创建 gRPC 客户端和服务器》

仔细回想了一下,这部分确实没有什么值得说的,官方文档已经非常的详细了。唯一不同的感受就是,net core 需要什么功能的话,需要通过nuget来安装;这点与 net framework 大有不同,framework 更像是,一次帮你全部装好。

Entity Framework Core

旧的WCF项目,数据库访问使用的是 Entity Framework + Linq + MySql。需要安装的 Nuget 包:

另外,还需要下载安装 mysql-connector-net-8.0.21.msi 来访问数据库。其中有一个 Scaffold-DbContext 的bug 99419 TINYINT(1) 转化为 byte,而不是预期的 bool。这个问题将会在 8.0.22 版本中修复,目前只能手动修改。
EF当然是 Database First 了,生成EF代码需要在Package Manager Console用到 Scaffold-DbContext 命令,有三点需要注意:

怎么用asp.net core+gRPC实现旧WCF项目迁移

我的命令:Scaffold-DbContext -Connection "server=10.50.40.50;port=3306;user=myuser;password=123456;database=dbname" -Provider MySql.Data.EntityFrameworkCore -OutputDir "EFModel" -ContextDir "Context" -Project "DataAccess" -Context "BaseEntities" -UseDatabaseNames -Force

其他建议:

public class Entities : BaseEntities
{
   private static string _lstDBString;

   public static void SetDefaultDBString(string _dbString)
   {
       if (string.IsNullOrEmpty(_lstDBString))
       {
           _lstDBString = _dbString;
       }
   }

   protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
   {
       if (!optionsBuilder.IsConfigured)
       {
           optionsBuilder.UseLazyLoadingProxies().UseMySQL(_lstDBString);
       }
   }
}
public void ConfigureServices(IServiceCollection services)
{
   string _dbString = Configuration.GetConnectionString("LstDatabase");
   services.AddDbContext<DataAccess.Context.Entities>(
       options => options.UseLazyLoadingProxies().UseMySQL(_dbString));
   services.AddGrpc();
}
{
   "ConnectionStrings": {
       "LstDatabase": "server=127.0.0.1;port=3306;user=myuser;password=123456;database=dbname"
   },
   "log4net": "log4net.config",
   "Logging": {
       "LogLevel": {
           "Default": "Information",
           "Microsoft": "Warning",
           "Microsoft.Hosting.Lifetime": "Information"
       }
   },
   "AllowedHosts": "*"
}

部署到 Ubuntu

生产环境运行的服务器是 Ubuntu 14.04.6 LTS,在《ubuntu Releases wiki》上描述,14版本在去年已经停止了标准支持,而 .net core 的 runtime 最低支持也是 Ubuntu 16.04.6 LTS,只好选择最新的版本Ubuntu 20.04.1 LTS

安装Ubuntu Server系统小插曲:IT支持部门的同事,帮忙重装了两遍系统,一次14.04桌面版,一次20.04服务器版;安装20版本后,发现网卡没有启用,主机后面网线的灯都没有亮起来。
由于我和他都不熟悉Ubuntu系统,网上查找办法,然后用手机拍照,再来服务器上尝试,搞了好一会儿,才连上网络,SSH也居然没有启用????。可能 Ubuntu 还是比较适合做桌面系统吧。

然后参考 《在 Ubuntu 上安装 .NET Core SDK 或 .NET Core 运行时》,安装 net core的环境,最初用的是 aspnetcore-runtime ,在测试的时候发现,gRPC需要 HTTPS。折腾了半天的 HTTPS,一会儿需要签名,一会儿还要生成密钥,一会儿还要放到指定的位置,可信任的证书还要去还要折腾????????。折腾了半天,脑壳一团浆糊。只好又安装了 dotnet-sdk,这个是自带开发的证书,反正是将就用把。

剩下的就比较简单了,编译发布asp.net core,打包上传到服务器,然后运行dotnet GrpcServiceLST.dll --urls "http://*:5000;http://*:5001"。打开浏览器测试访问,没毛病。

客户端的编写

在编写windows客户端的时候,遇到个问题:《.NET Core 中的 gRPC 客户端工厂集成》推荐的插件 Grpc.Net.ClientFactory 只能适用于 net core,而大部分客户的 windows7 系统不会安装 net core;如果想在 net framework 上使用 gRPC的话,只能用原生的方法来自己实现

使用 proto 文件生成代码的方法,与上面的一致,只需要把 Server Only 改为 Client Only ;代码部分要注意,部署的 HTTPS 是不受信任的,需要额外处理一下。

/// net core 3.1
private void button2_Click(object sender, EventArgs e)
{
   // 取消不受信任
   var httpHandler = new HttpClientHandler();
   httpHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
   var channel = GrpcChannel.ForAddress("https://10.50.40.237:5001", new GrpcChannelOptions { HttpHandler = httpHandler });
   var client = new UserManagement.UserManagementClient(channel);
   var _param = new GrpcServiceLST.Protos.LoginRequestV2()
   {
       UserName = "user",
       Password = "123456"
   };
   var reply = client.UserLoginOSDShadowEx(_param);
   MessageBox.Show("net core login: " + reply.Message);
}

/// framework 4.0
private void button1_Click(object sender, EventArgs e)
{
   var channel = new Channel("10.50.40.237:5000", ChannelCredentials.Insecure);
   var client = new UserManagement.UserManagementClient(channel);
   var _param = new GrpcServiceLST.Protos.LoginRequestV2()
   {
       UserName = "user",
       Password = "123456"
   };
   var _reply = client.UserLoginOSDShadowEx(_param);
   MessageBox.Show("framework login:" + _reply.Message);
}

经过测试发现,net core 的gRPC桌面程序 不支持 http 的访问;net framework 的桌面程序使用gRPC原生版本,只能访问 http 端口 5000 ,不能访问 https 端口 5001 ,不能用 http 或者 https 这样的前缀(如: http://10.50.40.237:5000),localhost这种域名也无法解析


HTTPHTTPS域名IP
net core gRPC客户端x
framework gRPC客户端xx

最最要命的是,在 win7 系统上,安装了 net core ,使用 Grpc.Net.ClientFactory 居然也不可以访问。在github上面找到了答案, win7 不会支持 http2 ,并且 win7 微软已经在2020 年1 月14 日停止提供支持。

issues : ASP.NET Core uses the operating system for HTTP/2 TLS support. macOS may support hosting servers with HTTP/2 TLS in the future, Windows 7 will not.

到此,相信大家对“怎么用asp.net core+gRPC实现旧WCF项目迁移”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. ASP.NET Core开发之HttpContext
  2. ASP.NET WEB API的使用示例

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

asp.net core grpc

上一篇:大数据云桌面应用的三大疑虑以及解决办法是什么

下一篇:大数据云教室解决方案和传统PC方案的区别是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》