加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 在ServiceStack中使用ICacheClient和protobuf时出现编码/

发布时间:2020-12-15 21:39:20 所属栏目:百科 来源:网络整理
导读:我正在使用当前的ServiceStack与protobuf序列化. 添加ICacheClient以缓存我的响应时,从缓存客户端发送的二进制答案与没有任何缓存客户端的原始响应具有不同的编码/二进制序列化. 这导致了客户端的反序列化问题,我正在使用预编译的反序列化器. 例如,在Service
我正在使用当前的ServiceStack与protobuf序列化.

添加ICacheClient以缓存我的响应时,从缓存客户端发送的二进制答案与没有任何缓存客户端的原始响应具有不同的编码/二进制序列化.

这导致了客户端的反序列化问题,我正在使用预编译的反序列化器.

例如,在ServiceStack服务器端使用ICacheClient时,在客户端发生此protobuf异常:

OverflowException: Number overflow.
ProtoBuf.ProtoReader.TryReadUInt32VariantWithoutMoving (Boolean trimNegative,System.UInt32& value)
ProtoBuf.ProtoReader.ReadUInt32Variant (Boolean trimNegative)
ProtoBuf.ProtoReader.ReadUInt32 () MyModelSerializer.Read (My.Models.MyDataModel,ProtoBuf.ProtoReader )

(我相信这是一个随机的例外,非常肯定也会出现其他例外情况.以此为例.)

MemoryCacheClient和Redis缓存客户端的行为相同.

这是我初始化protobuf的方式:

ContentTypeFilters.Register(ContentType.ProtoBuf,(reqCtx,res,stream) => ProtoBuf.Serializer.NonGeneric.Serialize(stream,res),ProtoBuf.Serializer.NonGeneric.Deserialize);

Cache Client初始化如下:

container.Register<ICacheClient>(new MemoryCacheClient());

(或者Redie在this guide之后).

这是通过线路的缓存的protobuf序列化数据看起来和未缓存的数据的不同之处:

Big Image

未缓存的响应似乎以不同方式编码/序列化.

我有什么办法可以解决这个编码问题,使Redis或Memory-ICacheClient与protobuf兼容吗?

更新:我调查了一下,这些是我的发现:

>要存储在缓存提供程序中(无论是Redis os Memory),protobuf二进制流通过HttpResponseFilter-> SerializeToString中的StreamReader“转换”为字符串,使用“UTF8 without BOM”-Encoding,它本身被称为通过CacheClientExtensions-> Cache().
>第一个问题:CacheClientExtensions-> Cache()然后返回to-string-serialized DTO,使protobuf已经不??可能反序列化了.第一个解决方案:在CacheClientExtensions-> Cache()中返回原始DTO.但这只适用于第一个非缓存响应,因为缓存的响应尚未正确反序列化.这将我们带到了
>第二个问题:再次从缓存中获取数据需要对protobuf的二进制数据进行正确的字符串序列化,以便首先将其放入缓存中.我知道它将使用via base64.
>第三个问题:目前似乎无法在运行时通过HttpResponseFilter-> SerializeToString中的StreamReader替换当前的流到字符串转换,对不对?
>第四个问题:从缓存中获取数据时,必须再次进行base64解码.

解决方法

我正在挖掘ServiceStack代码,但发现没有可能实现我的要求(我真的希望我没有忽略一些东西).

所以我对ServiceStack进行了一些更改,这些更改允许使用自定义TextSerializers,然后用于序列化到字符串bevor将DTO推送到缓存客户端.

在这里看到我的差异:
https://github.com/derFunk/ServiceStack/commit/93f62c7d7e44a303c88a81c3096b9757daba4c7c

它可以用于我的目的,虽然它可能没有经过全面测试,但仍然是非常重要的原型.

如果一些ServiceStack忍者可以审查我正在做的事情,我会很感激,也许它最终会被拉入请求.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读