現在、ソケットを使用して、Silverlight 3 クライアントと .NET3.5 サービスの間でメッセージを送信しようとしています。TCP 接続を正常にセットアップしてデータを送信できますが、DataContract のシリアル化と逆シリアル化に問題があります。
現在、この作業を行うために WCF PollingDuplex バインディングを使用していますが、そのパフォーマンスに満足していないため、DataContract 属性を利用しようとしながらソケットを試しています。私が持っているコードは次のとおりです。
// Client
public void Send(ActionMessage actionMessage)
{
DataContractSerializer dcs =
new DataContractSerializer(actionMessage.GetType());
MemoryStream memoryStream = new MemoryStream();
dcs.WriteObject(memoryStream, actionMessage);
byte[] sendBuffer = new byte[4096];
memoryStream.Position = 0;
memoryStream.Read(sendBuffer, 0, sendBuffer.Length);
SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs();
socketAsyncEventArgs.SetBuffer(sendBuffer, 0, sendBuffer.Length);
if(!_socket.SendAsync(socketAsyncEventArgs))
HandleSendComplete(socketAsyncEventArgs);
}
// Service
private byte[] _recieveBuffer = new byte[4096];
private int _receivedLength;
private void socket_OnReceiveComplete(IAsyncResult asyncResult)
{
_receivedLength += _tcpClient.Client.EndReceive(asyncResult);
// See if there's more data that we need to grab
if (_receivedLength < _recieveBuffer.Length)
{
// Need to grab more data so receive remaining data
_tcpClient.Client.BeginReceive(_recieveBuffer, _receivedLength,
_recieveBuffer.Length - _receivedLength, SocketFlags.None,
new AsyncCallback(socket_OnReceiveComplete), null);
return;
}
MemoryStream memoryStream = new MemoryStream();
memoryStream.Position = 0;
memoryStream.Write(_recieveBuffer, 0, _recieveBuffer.Length);
DataContractSerializer dcs = new DataContractSerializer(typeof(ActionMessage));
object o = dcs.ReadObject(memoryStream);
ActionMessage actionMessage = (ActionMessage) o;
}
XmlException: Unexpected End of File をスローするのは ReadObject 行です。受信時にバイト配列 (_recieveBuffer) の末尾の 0 を切り捨てたり、最後に 0 を 1 つだけ残したりするなど、さまざまなことを試しましたが、何も機能していないようです。クライアント側とサーバー側の byte[] バッファーを確認しましたが、最初と最後で同じ値を持ち、同じ長さです。また、actionMessage.GetType() と typeof(ActionMessage) を DataContractSerializer のパラメーターとして使用してみましたが、違いはありません...
ここで何が欠けていますか: dataContractSerializer.Write() が dataContractSerializer.Read() によって生成された出力を受け入れないのはなぜですか?
これに当たるまでは良い一日を過ごしていました...同じ問題を抱えている別の男を見つけましたが、サービス側でmemoryStream.Position = 0を設定するという解決策が提供されました...
前もって感謝します。