1 つのサーバーと多数のクライアント間の通信には、protobuf-net と .NET の TCPClient & NetworkStream を使用します。メッセージの送信には、両側で次の方法を使用します。
public static bool WriteProtocolBufferToStream(System.IO.Stream stream, object protoBufObject)
{
// ... check parameters ...
// ... Determine the 'fieldNumber' of the 'protoBufObject' via a helper dictionary ...
if (fieldNumber > -1)
{
try { Serializer.NonGeneric.SerializeWithLengthPrefix(stream, protoBufObject, ProtoBuf.PrefixStyle.Base128, fieldNumber); }
catch (Exception ex)
{
Logger.Instance.Error("Exception: " + ex.Message);
return false;
}
}
else
{
Logger.Instance.Error("unknown message type");
return false;
}
return true;
}
一部のクライアントと少数のメッセージのみの小規模なシナリオでは、すべて問題ありません。しかし、約 40 のクライアントと多くの交換メッセージがあるシナリオでは問題があります。メッセージは非常に小さい (1 ~ 5 個の小さな文字列を含む) ですが、サーバーがこれらのメッセージを複数 (最大 200) 同時に送信する場合があります。
しばらくすると (数分から数時間)、次の例外がスローされます。
ArgumentException: Cannot write to stream. Parameter name: dest
ソースは、protobuf-net のProtoWriterクラス コンストラクターです。destCanWrite
のプロパティが falseであるため、この例外がスローされます。私の質問は:しばらくすると true から false に変わるのはなぜですか? バッファのオーバーフローと関係がありますか (同時に多くのメッセージを送信するため)。どうすれば修正できますか?NetworkStream
CanWrite
編集:
@[Marc Gravell] がすでに指摘したように、は破棄されるため、true から false にNetworkStream
変更されます。CanWrite
たとえば、ストリームオブジェクトのWriteTimeout
プロパティにアクセスしようとすると、次のようになります。
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'.
at System.Net.Sockets.Socket.GetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName)
at System.Net.Sockets.NetworkStream.get_WriteTimeout()
at Utilities.CommunicationHelper.WriteProtocolBufferToStream(NetworkStream stream, Object protoBufObject)
...
コード内でソケットの破棄を引き起こす可能性のあるものをまだ探しています。ソケットがしばらく (数時間) 後に破棄される原因として他に何が考えられますか?