麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > .NET > 正文

如何為asp.net core添加protobuf支持詳解

2024-07-10 13:32:58
字體:
來源:轉載
供稿:網友

前言

在一些性能要求很高的應用中,使用protocol buffer序列化,優于Json。而且protocol buffer向后兼容的能力比較好。

由于Asp.net coreldraw/180070.html">core 采用了全新的MiddleWare方式,因此使用protobuf序列化,只需要使用Protobuf-net修飾需要序列化的對象,并在MVC初始化的時候增加相應的Formatter就可以了。

沒時間解釋了,快上車。

通過NuGet獲取Zaabee.AspNetCoreProtobuf

Install-Package Zaabee.AspNetCoreProtobuf

在Startup.cs文件中修改ConfigureServices方法

public void ConfigureServices(IServiceCollection services){  services.AddMvc(options => { options.AddProtobufSupport(); });}

搞掂……這時候你就可以通過application/x-protobuf的content-type來讓asp.net core使用protobuf來進行序列化/反序列化。

測試代碼

在asp.net core項目中添加以下DTO

[ProtoContract]public class TestDto{  [ProtoMember(1)] public Guid Id { get; set; }  [ProtoMember(2)] public string Name { get; set; }  [ProtoMember(3)] public DateTime CreateTime { get; set; }  [ProtoMember(4)] public List<TestDto> Kids { get; set; }  [ProtoMember(5)] public long Tag { get; set; }  [ProtoMember(6)] public TestEnum Enum { get; set; }}public enum TestEnum{  Apple,  Banana,  Pear}

新建一個XUnit項目,通過Nuget引用Microsoft.AspNetCore.TestHost,建立一個測試類

public class AspNetCoreProtobufTest{  private readonly TestServer _server;  private readonly HttpClient _client;  public AspNetCoreProtobufTest()  {    _server = new TestServer(      new WebHostBuilder()        .UseKestrel()        .UseStartup<Startup>());    _client = _server.CreateClient();  }  [Fact]  public void Test()  {    // HTTP Post with Protobuf Response Body    _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-protobuf"));    var dtos = GetDtos();    var stream = new MemoryStream();    ProtoBuf.Serializer.Serialize(stream, dtos);    HttpContent httpContent = new StreamContent(stream);    // HTTP POST with Protobuf Request Body    var responseForPost = _client.PostAsync("api/Values", httpContent);    var result = ProtoBuf.Serializer.Deserialize<List<TestDto>>(      responseForPost.Result.Content.ReadAsStreamAsync().Result);    Assert.True(CompareDtos(dtos,result));  }  private static bool CompareDtos(List<TestDto> lstOne, List<TestDto> lstTwo)  {    lstOne = lstOne ?? new List<TestDto>();    lstTwo = lstTwo ?? new List<TestDto>();    if (lstOne.Count != lstTwo.Count) return false;    for (var i = 0; i < lstOne.Count; i++)    {      var dtoOne = lstOne[i];      var dtoTwo = lstTwo[i];      if (dtoOne.Id != dtoTwo.Id || dtoOne.CreateTime != dtoTwo.CreateTime || dtoOne.Enum != dtoTwo.Enum ||        dtoOne.Name != dtoTwo.Name || dtoOne.Tag != dtoTwo.Tag || !CompareDtos(dtoOne.Kids, dtoTwo.Kids))        return false;    }    return true;  }  private static List<TestDto> GetDtos()  {    return new List<TestDto>    {      new TestDto      {        Id = Guid.NewGuid(),        Tag = long.MaxValue,        CreateTime = DateTime.Now,        Name = "0",        Enum = TestEnum.Apple,        Kids = new List<TestDto>        {          new TestDto          {            Id = Guid.NewGuid(),            Tag = long.MaxValue - 1,            CreateTime = DateTime.Now,            Name = "00",            Enum = TestEnum.Banana          },          new TestDto          {            Id = Guid.NewGuid(),            Tag = long.MaxValue - 2,            CreateTime = DateTime.Now,            Name = "01",            Enum = TestEnum.Pear          }        }      },      new TestDto      {        Id = Guid.NewGuid(),        Tag = long.MaxValue - 3,        CreateTime = DateTime.Now,        Name = "1",        Enum = TestEnum.Apple,        Kids = new List<TestDto>        {          new TestDto          {            Id = Guid.NewGuid(),            Tag = long.MaxValue - 4,            CreateTime = DateTime.Now,            Name = "10",            Enum = TestEnum.Banana          },          new TestDto          {            Id = Guid.NewGuid(),            Tag = long.MaxValue - 5,            CreateTime = DateTime.Now,            Name = "11",            Enum = TestEnum.Pear          }        }      }    };  }}

為什么要用protobuf?

因為快……在我們這邊使用業務數據的測試中,protobuf的序列化/反序列化性能大概是Json.net的三倍,序列化后的體積大概只有Json的二分之一,這可以在相當程度上提高webapi的吞吐性能。

另外就是Json對于浮點數的處理存在精度丟失,因為JS的number類型的安全整數是53位。當我們使用雪花算法來提供全局遞增ID時會因為精度丟失導致重復主鍵。而且情況不僅如此,由于同樣原因傳遞DateTime類型也會因為毫秒不一致導致時間匹配錯誤。一般的解決方法是使用字符串傳遞,不過這畢竟屬于偏方并沒有從根源上解決問題,因此我們還是直接使用protobuf來處理。

protobuf的缺點

DTO層必須引用protobuf-net來添加特性,這在一定程度上導致了代碼的侵入。基本上DTO屬于POCO,依賴第三方包的話總覺得有點不貞潔……另外就是protobuf序列化后的數據不具有可視化,因此如果是使用消息隊列或者請求監控的地方,就要綜合考慮protobuf是否適合使用場景。

原理

asp.net core是基于中間件方式來實現,其自帶默認的JsonFormater(基于Json.net),asp.net core會根據content type來選擇對應的Formater來處理對象的序列化,當中包括InputFormatter(反序列化)和OutputFormatter(序列化)。因此除了protobuf,我們還可以添加或者替換其它的序列化方式,例如使用Jil來代替Json.net來提高Json性能。

以上實現以及Demo和測試的源代碼已放到 GitHub 上。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到ASP.NET教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 黄污网站在线观看 | 精品国产一区二区三区成人影院 | 免费视频a | 男人的天堂色偷偷 | 欧美亚洲啪啪 | 久久久久久久久亚洲精品 | 亚洲第一成人av | 国产美女视频一区二区三区 | 亚洲国产精品高潮呻吟久久 | 美女久久久久 | 第四色成人网 | 777sesese| 免费观看视频在线观看 | 中文字幕欧美在线 | 色蜜桃av | 久久精品视频日本 | 草久影视| 把娇妻调教成暴露狂 | 久久影院免费观看 | 午夜视频大全 | 欧美亚成人 | 全黄裸片武则天一级第4季 九色p | 午夜国产福利 | 久久精品视频免费观看 | 午夜视频导航 | 免费在线观看国产 | 久久精品亚洲成在人线av网址 | 欧美精品免费一区二区三区 | 91 成人| 激情在线视频 | 欧美日本91精品久久久久 | 依依成人综合 | 精品国产一区二区三区久久久 | av手机在线免费播放 | 国产精品99久久久久久大便 | 黄色av免费电影 | 欧美四级在线观看 | 99国语露脸久久精品国产ktv | 欧美中文字幕一区二区 | 特级黄色小说 | 亚洲午夜久久久精品一区二区三区 |