91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用asp.net core+gRPC實現舊WCF項目遷移

發布時間:2021-12-06 11:54:39 來源:億速云 閱讀:150 作者:iii 欄目:大數據

本篇內容主要講解“怎么用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.Data.EntityFrameworkCore Mysql的EF核心庫;

  • Microsoft.EntityFrameworkCore.Proxies 《Lazy loading》 懶加載的插件;

  • Microsoft.EntityFrameworkCore.DesignMicrosoft.EntityFrameworkCore.Tools 這兩個插件,用于生成代碼;

另外,還需要下載安裝 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 命令,有三點需要注意:

  • Start up 啟始項目一定要是引用它的項目,并且編譯成功的;

  • Default project 生成后,代碼存放的項目;

  • 如果生成失敗,提示:“Your startup project 'XXXX' doesn't reference Microsoft.EntityFrameworkCore.Design. This package is required for the Entity Framework Core Tools to work. Ensure your startup project is correct, install the package, and try again.”。編輯項目文件 csproj 移除 <PrivateAssets>All</PrivateAssets> 從 "Microsoft.EntityFrameworkCore.Design"和"Microsoft.EntityFrameworkCore.Tools"中;

怎么用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

其他建議:

  • Library類庫最好是 netstandard 方便移植;

  • 新建一個類來繼承BaseEntities,覆蓋 OnConfiguring 方法,可配置的數據庫連接字符串;

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);
       }
   }
}
  • 最好采用 asp.net core 的框架注入;鑒于項目的原因,假如強行采用的話,改動比較大,只好放棄;

public void ConfigureServices(IServiceCollection services)
{
   string _dbString = Configuration.GetConnectionString("LstDatabase");
   services.AddDbContext<DataAccess.Context.Entities>(
       options => options.UseLazyLoadingProxies().UseMySQL(_dbString));
   services.AddGrpc();
}
  • 數據庫鏈接字符串有多種存放的方式,有更加安全的方式;而我采用簡單方式存放在 appsettings.json

{
   "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項目遷移”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

茂名市| 烟台市| 聊城市| 大丰市| 定结县| 黎平县| 江津市| 南城县| 浦江县| 北辰区| 福泉市| 芜湖县| 南川市| 静乐县| 临高县| 卢氏县| 宁城县| 临武县| 台北县| 富锦市| 大渡口区| 秦安县| 富裕县| 修水县| 冕宁县| 湾仔区| 唐海县| 墨江| 长春市| 平定县| 沁水县| 萨迦县| 赫章县| 夹江县| 长宁区| 棋牌| 荆门市| 山东| 鄢陵县| 高台县| 江山市|