添加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序列化数据看起来和未缓存的数据的不同之处:
未缓存的响应似乎以不同方式编码/序列化.
我有什么办法可以解决这个编码问题,使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进行了一些更改,这些更改允许使用自定义TextSerializers,然后用于序列化到字符串bevor将DTO推送到缓存客户端.
在这里看到我的差异:
https://github.com/derFunk/ServiceStack/commit/93f62c7d7e44a303c88a81c3096b9757daba4c7c
它可以用于我的目的,虽然它可能没有经过全面测试,但仍然是非常重要的原型.
如果一些ServiceStack忍者可以审查我正在做的事情,我会很感激,也许它最终会被拉入请求.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。