internal async void ReceiveMessages()
{
while(true) try
{
var tinyBuf = new byte[sizeof(ushort)];
ushort length;
if (_semantics.PeerLength == null)
{
// read the message length (2 bytes)
await SocketReceiveAsync(_socket, tinyBuf, 0, sizeof (ushort));
if (!BitConverter.IsLittleEndian)
Array.Reverse(tinyBuf);
length = BitConverter.ToUInt16(tinyBuf, 0);
}
else
length = _semantics.PeerLength.Value;
uint? id;
if (_semantics.DisableRequests)
id = null;
else
{
// read the id (1 byte if no id, 4 bytes if there is)
var idBuf = new byte[sizeof (uint)];
await SocketReceiveAsync(_socket, idBuf, 0, 1);
if (idBuf[0] == 0)
id = null;
else
{
await SocketReceiveAsync(_socket, idBuf, 1, sizeof (uint) - 1);
if (!BitConverter.IsLittleEndian)
Array.Reverse(tinyBuf);
id = BitConverter.ToUInt32(idBuf, 0);
}
}
var buf = new byte[length];
for (int bytes = 0; bytes < length; )
bytes += await SocketReceiveAsync(_socket, buf, bytes, length-bytes);
if (id == null || !_replyReceivers.ContainsKey(id.Value))
{
TaskCompletionSource<WireContext> tcs;
do
{
tcs = _receivers.Take();
} while (tcs.Task.IsCanceled || tcs.Task.IsFaulted);
tcs.SetResult(new WireContext(this, buf, id));
}
else
{
_replyReceivers[id.Value].SetResult(new WireContext(this, buf, id));
_replyReceivers.Remove(id.Value);
}
}
catch (SocketException)
{
Disconnect();
return;
}
catch (ObjectDisposedException)
{
Disconnect();
return;
}
}