分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

插上腾飞的翅膀:为asp.net core添加protobuf支持

发布时间:2023-09-06 01:43责任编辑:白小东关键词:暂无标签

没时间解释了,快上车。

通过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", ????????????????https://i.cnblogs.com/EditCategories.aspx?catid=1 ??????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的吞吐性能。

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上。

最后给大家拜个晚年,祝大家新年快乐~

插上腾飞的翅膀:为asp.net core添加protobuf支持

原文地址:https://www.cnblogs.com/Mutuduxf/p/8457011.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved