1

ネットワーク クライアント/サーバー アプリケーションで protobuf-net を使用しています。データの各パケットは、メッセージを圧縮するために BZip2Input/Output ストリームで圧縮されます。これは数週間うまくいきましたが、最近サーバーのオブジェクトを変更したところ、BZip2Input ストリームがシークをサポートしていないという例外が発生しています (これはサポートしていません)。これは、protobuf が一部のフィールドをスキップできることを検出し、適切にスキップしようとするためだと思います。

この動作を無効にし、データを読み取って protobuf-net にフィールドをスキップさせる方法はありますか? (求めていない)。

更新: 以下に完全なスタック トレースを追加しました。あなたのコメントに基づいて、ストリームには CanSeek コールバックにバグがあるはずです。どう思いますか?

Server First Chance Exception: BZip2InputStream Seek n
ot supported Stack Trace:    at ICSharpCode.SharpZipLib.BZip2.BZip2InputStream.S
eek(Int64 offset, SeekOrigin origin)
Server_NewRequestReceived Exception: System.NotSupportedException: BZip2InputStream Seek not supported
   at ICSharpCode.SharpZipLib.BZip2.BZip2InputStream.Seek(Int64 offset, origin)
   at ProtoBuf.ProtoReader.Seek(Stream source, Int32 count, Byte[] buffer)
   at ProtoBuf.ProtoReader.SkipField()
   at proto_2(Object, ProtoReader)
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSeriali    zer.Read(Object value, ProtoReader source)
   at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, source)
   at ProtoBuf.Meta.TypeModel.TryDeserializeAuxiliaryType(ProtoReader reader, format, Int32 tag, Type type, ref Object value, Boolean skipOtherFields, asListItem, Boolean autoCreate, Boolean insideList)
   at ProtoBuf.Meta.TypeModel.TryDeserializeList(TypeModel model, ader, DataFormat format, Int32 tag, Type listType, Type itemType, ref Object value)

   at ProtoBuf.Meta.TypeModel.TryDeserializeAuxiliaryType(ProtoReader reader, format, Int32 tag, Type type, ref Object value, Boolean skipOtherFields, asListItem, Boolean autoCreate, Boolean insideList)
   at ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoReader reader, Type type, value, Boolean noAutoCreate)
   at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type, SerializationContext context)
   at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type)
   at ProtoBuf.Serializer.Deserialize(Stream source)

SharpZipLib バグを回避するために、このクラスを作成しました。

    public class NonSeekableStreamWrapper : Stream
    {
        public Stream BaseStream { get; private set; }

        public NonSeekableStreamWrapper(Stream baseStream)
        {
            BaseStream = baseStream;
        }

        public override void Flush()
        {
            BaseStream.Flush();
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return BaseStream.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            BaseStream.SetLength(value);
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return BaseStream.Read(buffer, offset, count);
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            BaseStream.Write(buffer, offset, count);
        }

        public override bool CanRead
        {
            get { return true; }
        }

        public override bool CanSeek
        {
            get { return false; }
        }

        public override bool CanWrite
        {
            get { return false; }
        }

        public override long Length
        {
            get { return BaseStream.Length; }
        }

        public override long Position { get; set; }
    }
4

1 に答える 1