public void SendInMessageList(List <SerializedRelayMessage> messages) { ResourcePoolItem <MemoryStream> pooledBuffer; MemoryStream nextMessageChunk; int chunkLength = defaultChunkLength; int cursor = 0; if (messages.Count > 0) { if (chunkLength == 0 || chunkLength > messages.Count) { //0 means "don't chunk" chunkLength = messages.Count; } pooledBuffer = bufferPool.GetItem(); try { nextMessageChunk = pooledBuffer.Item; byte[] lengthBytes = BitConverter.GetBytes(chunkLength); while (cursor < messages.Count) { //make sure that the next chunk doesn't go past the end of the list if ((cursor + chunkLength) > messages.Count) { chunkLength = messages.Count - cursor; BitConverterEx.WriteBytes(lengthBytes, 0, chunkLength); } nextMessageChunk.Write(lengthBytes, 0, 4); for (int end = cursor + chunkLength; cursor < end; cursor++) { messages[cursor].MessageStream.WriteTo(nextMessageChunk); } socketClient.SendOneWay((int)SocketCommand.HandleOneWayMessages, nextMessageChunk); nextMessageChunk.Seek(0, SeekOrigin.Begin); nextMessageChunk.SetLength(0); } } finally { bufferPool.ReleaseItem(pooledBuffer); } } }
private static void _writeMessageHeader( Stream destination, bool networkOrdered, int messageLength, short commandId, short messageId, bool isRoundTrip) { using (var buffer = _headerBufferPool.Borrow()) { if (networkOrdered) { BitConverterEx.WriteBytes(buffer.Item, _messageStarterOffset, _messageStarterNetwork); BitConverterEx.WriteBytes(buffer.Item, _messageLengthOffset, IPAddress.HostToNetworkOrder(messageLength + _envelopeSize)); if (messageId == 0) { BitConverterEx.WriteBytes(buffer.Item, _messageCommandIdOffset, IPAddress.HostToNetworkOrder((int)commandId)); } else { BitConverterEx.WriteBytes(buffer.Item, _messageCommandIdOffset, IPAddress.HostToNetworkOrder(messageId)); BitConverterEx.WriteBytes(buffer.Item, _messageCommandIdOffset + sizeof(short), IPAddress.HostToNetworkOrder(commandId)); } BitConverterEx.WriteBytes(buffer.Item, _isSyncOffset, isRoundTrip); } else { BitConverterEx.WriteBytes(buffer.Item, _messageStarterOffset, _messageStarterHost); BitConverterEx.WriteBytes(buffer.Item, _messageLengthOffset, messageLength + _envelopeSize); if (messageId == 0) { BitConverterEx.WriteBytes(buffer.Item, _messageCommandIdOffset, (int)commandId); } else { BitConverterEx.WriteBytes(buffer.Item, _messageCommandIdOffset, commandId); BitConverterEx.WriteBytes(buffer.Item, _messageCommandIdOffset + sizeof(short), messageId); } BitConverterEx.WriteBytes(buffer.Item, _isSyncOffset, isRoundTrip); } destination.Write(buffer.Item, 0, _headerSize); } }
/// <summary> /// Writes the message to send to a socket server. /// </summary> /// <typeparam name="T"> /// <para>The type of object contained in the message.</para> /// </typeparam> /// <param name="destination">The destination stream to write the message to.</param> /// <param name="networkOrdered"> /// <para><see langword="true"/> to use network-ordered endianness for the header /// information; <see langword="false"/> otherwise.</para></param> /// <param name="commandId">The command id to send to the server.</param> /// <param name="messageId">The message id.</param> /// <param name="isRoundTrip"> /// <para><see langword="true"/> if a reply is expected from the server; /// <see langword="false"/> otherwise.</para> /// </param> /// <param name="message">The object to encode in the message.</param> /// <param name="messageSerializer"> /// <para>A method that will serialize <paramref name="message"/> into <paramref name="destination"/>.</para> /// </param> public static void WriteMessage <T>( Stream destination, bool networkOrdered, short commandId, short messageId, bool isRoundTrip, T message, Procedure <T, Stream> messageSerializer) { if (destination == null) { throw new ArgumentNullException("destination"); } if (messageSerializer == null) { throw new ArgumentNullException("messageSerializer"); } if (!destination.CanSeek) { throw new ArgumentException("destination must be seakable (Stream.CanSeek)", "destination"); } int startPosition = (int)destination.Position; _writeMessageHeader(destination, networkOrdered, -1, commandId, messageId, isRoundTrip); messageSerializer(message, destination); int endPosition = (int)destination.Position; destination.Seek(startPosition + _messageLengthOffset, SeekOrigin.Begin); int messageLength = endPosition - startPosition + _terminatorSize; if (networkOrdered) { messageLength = IPAddress.HostToNetworkOrder(messageLength); } using (var buffer = _headerBufferPool.Borrow()) { BitConverterEx.WriteBytes(buffer.Item, 0, messageLength); destination.Write(buffer.Item, 0, sizeof(int)); } destination.Seek(endPosition, SeekOrigin.Begin); _writeMessageTerminator(destination, networkOrdered); }