質問

私はXMPP(ジングル)ストリームを送信するためにXmlWriterを使用しています。それは次のように終わるXMLを意味TLSを交渉する際にXMPPプロトコルは、XMLストリームを置き換えます:

<stream>
 <features>
  ...
 </features>

 ...TLS gets negotiated...

<stream>
 ...
</stream>
2ストリームの開始タグがあるので、十分に形成されていないされているアップ

XML終了。

私は何をしたい、それは私がより良い私のコードをモジュール化することができます、私は前にTLSネゴシエーションに使用していますXmlWriterを捨てて新しいものを作成することです。しかし、私は確信して、それがXMPPプロトコルを破る終値ストリーム終了要素が送信されます配置されます。

作るためにmyXmlWriter.Close()を呼び出すとき 私はそれが優れたエンド要素を送信せずにXmlWriterを閉じることができとにかくありますか?

役に立ちましたか?

解決

を使用すると、基本ストリームからのXmlWriterを切断するために使用できる中間ストリームを作成します。

あなたは生産にこれを入れる前に、これは、それはそうテスト、最もエレガントなソリューション、およびニーズの作業以下のコードではありませんが、それはアイデアについてです。

public class DummyStream : Stream
{
    public DummyStream(Stream baseStream)
    {
        if (baseStream == null)
            throw new ArgumentNullException("baseStream");

        BaseStream = baseStream;
    }

    public Stream BaseStream { get; private set; }

    public void DisconnectBaseStream()
    {
        BaseStream = null;
    }

    private Stream GetBaseStream()
    {
        return BaseStream ?? Stream.Null;
    }

    public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
    {
        return GetBaseStream().BeginRead(buffer, offset, count, callback, state);
    }

    public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
    {
        return GetBaseStream().BeginWrite(buffer, offset, count, callback, state);
    }

    public override bool CanRead
    {
        get { return GetBaseStream().CanRead; }
    }

    public override bool CanSeek
    {
        get { return GetBaseStream().CanSeek; }
    }

    public override bool CanTimeout
    {
        get { return GetBaseStream().CanTimeout; }
    }

    public override bool CanWrite
    {
        get { return GetBaseStream().CanWrite; }
    }

    public override void Close()
    {
        // We do not close the BaseStream because this stream
        // is just a wrapper.

        // GetBaseStream().Close();
    }

    public override ObjRef CreateObjRef(Type requestedType)
    {
        return GetBaseStream().CreateObjRef(requestedType);
    }

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);

        // We do not dispose the BaseStream because this stream
        // is just a wrapper.
    }

    public override int EndRead(IAsyncResult asyncResult)
    {
        return GetBaseStream().EndRead(asyncResult);
    }

    public override void EndWrite(IAsyncResult asyncResult)
    {
        GetBaseStream().EndWrite(asyncResult);
    }

    public override bool Equals(object obj)
    {
        return GetBaseStream().Equals(obj);
    }

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

    public override int GetHashCode()
    {
        return GetBaseStream().GetHashCode();
    }

    public override object InitializeLifetimeService()
    {
        return GetBaseStream().InitializeLifetimeService();
    }

    public override long Length
    {
        get { return GetBaseStream().Length; }
    }

    public override long Position
    {
        get { return GetBaseStream().Position; }
        set { GetBaseStream().Position = value; }
    }

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

    public override int ReadByte()
    {
        return GetBaseStream().ReadByte();
    }

    public override int ReadTimeout
    {
        get { return GetBaseStream().ReadTimeout; }
        set { GetBaseStream().ReadTimeout = value; }
    }

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

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

    public override string ToString()
    {
        return GetBaseStream().ToString();
    }

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

    public override void WriteByte(byte value)
    {
        GetBaseStream().WriteByte(value);
    }

    public override int WriteTimeout
    {
        get { return GetBaseStream().WriteTimeout; }
        set { GetBaseStream().WriteTimeout = value; }
    }
}

このクラスはXmlWriterXmlWriterがに出力されるストリーム間のストリームとして使用されることを意味します。このクラスは、基本ストリームへXmlWriterから単純に転送したすべてのコールが、あなたはDisconnectBaseStreamを呼び出すと、それはもはやそれとベースストリームを制御することはできませんXmlWriterの転送を停止します。

あなたはこのように、このクラスを使用することができます:

using (var stream = /* stream used to communicate with */)
{
    using (var wrapperStream = new DummyStream(stream))
    using (var writer = XmlWriter.Create(wrapperStream))
    {
        // Do you work here.

        // Now, disconnect the dummy stream so that the XML writer
        // cannot send more data.

        wrapperStream.DisconnectBaseStream();

        // End of the using block will close the XmlWriter and it
        // cannot send more data to the base stream.
    }

    // Perform TLS negotiation etc...
}
ここでも、DummyStreamは開始点であり、いくつかの作業が必要になります。あなたは、例えばと、いくつかのチェックをしたいと思うでしょうので、あなたは、たとえば、XmlWriterがクラッシュします切断後の呼び出しを行っていないことを確認したくなるでしょうWrite方法がBaseStreamnullありそうならば、単に呼び出しをスキップします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top