В настоящее время я использую сокеты для отправки сообщений между клиентом Silverlight 3 и службой .NET3.5. Я могу нормально настроить TCP-соединение и отправлять данные, но моя проблема связана с сериализацией и десериализацией DataContracts.
В настоящее время мы используем привязку 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;
}
Это строка ReadObject, которая вызывает исключение XmlException: Unexpected End of File. Я пробовал разные вещи, включая усечение завершающих 0 из байтового массива (_recieveBuffer) при его получении, оставляя только один 0 в конце и т.д., но, похоже, ничего не работает. Я проверил буферы byte [] на стороне клиента и на стороне сервера, и они имеют одинаковые значения в начале и в конце и имеют одинаковую длину. Я также пробовал использовать actionMessage.GetType () и typeof (ActionMessage) в качестве параметров DataContractSerializer, но нет никакой разницы ...
Что я здесь упускаю: почему dataContractSerializer.Write () не принимает вывод, сгенерированный dataContractSerializer.Read ()?
У меня был хороший день, пока я не нажал на это ... Я нашел еще одного парня с той же проблемой, но предложенное решение, чтобы установить memoryStream.Position = 0 на стороне службы, не сработало ...
Заранее спасибо.