public static void StartListening(Connection connection) { Message.BeginReceive(connection, new AsyncCallback(ReceiveMessage), null); }
/// <summary> /// Receives a message over a specified Duplex Channel Connection. /// </summary> /// <param name="connection">Duplex Channel Connection</param> /// <param name="ar">Result (for Async pattern)</param> /// <returns>Received message</returns> public static Message EndReceive(out Connection connection, IAsyncResult ar) { AsyncResult myAr = (AsyncResult)ar; connection = myAr.Connection; try { connection.LockRead(); if (connection.Socket == null) { throw new MessageException("Connection closed.", null, connection); } SocketError socketError; int bytesRead = connection.Socket.EndReceive(myAr.InternalAsyncResult, out socketError); if (bytesRead == 0 || connection.Channel == null) { throw new MessageException("Connection closed.", new SocketException((int)socketError), connection); } // read message identifier var reader = connection.Reader; if (bytesRead < SizeOfGuid) { var rest = reader.Read(myAr.Buffer, bytesRead, SizeOfGuid - bytesRead); if (rest < SizeOfGuid - bytesRead) { throw new MessageException("Insufficient data received. Got " + bytesRead + " bytes.", new SocketException((int)socketError), connection); } } // read message header Message retVal = new Message(); retVal.Guid = new Guid(myAr.Buffer); int headerLength = reader.ReadInt32(); MemoryStream headerStream = new MemoryStream(reader.ReadBytes(headerLength)); if (headerStream.Length != headerLength) { throw new Exception("Not enough headers read..."); } retVal.Headers = TransportHeaderWrapper.Deserialize(headerStream); int bodyLength = reader.ReadInt32(); if (bodyLength > 0) { retVal.messageBodyBytes = reader.ReadBytes(bodyLength); if (retVal.messageBodyBytes.Length != bodyLength) { throw new Exception("Not enough body read..."); } System.Diagnostics.Debug.Assert(retVal.MessageBody.CanRead); } Message.BeginReceive(connection, myAr.Callback, myAr.AsyncState); return(retVal); } catch (Exception e) { throw new MessageException("Error receiving message", e, connection); } finally { connection.ReleaseRead(); } }
/// <summary> /// Receives a message over a specified Duplex Channel Connection. /// </summary> /// <param name="connection">Duplex Channel Connection</param> /// <param name="ar">Result (for Async pattern)</param> /// <returns>Received message</returns> public static Message EndReceive(out Connection connection, IAsyncResult ar) { AsyncResult myAr = (AsyncResult)ar; connection = myAr.Connection; try { connection.LockRead(); if (connection.Socket == null) { throw new MessageException("Connection closed.", null, connection); } int bytesRead = connection.Socket.EndReceive(myAr.InternalAsyncResult); if (bytesRead == 16) { Message retVal = new Message(); retVal.Guid = new Guid(myAr.Buffer); BinaryReader reader = connection.Reader; int headerLength = reader.ReadInt32(); MemoryStream headerStream = new MemoryStream(reader.ReadBytes(headerLength)); if (headerStream.Length != headerLength) { throw new Exception("Not enough headers read..."); } retVal.Headers = TransportHeaderWrapper.Deserialize(headerStream); int bodyLength = reader.ReadInt32(); if (bodyLength > 0) { retVal.messageBodyBytes = reader.ReadBytes(bodyLength); if (retVal.messageBodyBytes.Length != bodyLength) { throw new Exception("Not enough body read..."); } System.Diagnostics.Debug.Assert(retVal.MessageBody.CanRead); } Message.BeginReceive(connection, myAr.Callback, myAr.AsyncState); return(retVal); } else if (bytesRead == 0) { throw new MessageException("Connection closed.", null, connection); } else { throw new MessageException("Insufficient data received", null, connection); } } catch (Exception e) { throw new MessageException("Error receiving message", e, connection); } finally { connection.ReleaseRead(); } }