public async Task SendMessage(Message message, CancellationToken ct) { int msgSize = _minMsgSize; var payloadSize = 0; var payload = message.Payload; if (payload != null) { payloadSize = payload.Length; msgSize += payloadSize; } var buffer = ArrayPool <byte> .Shared.Rent(_sendBufferSize); var payloadIndex = 0; try { do { var partialPayloadSize = Math.Min(payloadSize - payloadIndex, _availablePayloadSize); var partialMsgSize = _minPartialMsgSize + partialPayloadSize; BufferHelper.CopyToIndex(BitConverter.GetBytes(partialMsgSize), buffer, _partialMsgSizeIndex); BufferHelper.CopyToIndex(BitConverter.GetBytes(msgSize), buffer, _msgSizeIndex); BufferHelper.CopyToIndex(BitConverter.GetBytes(payloadIndex), buffer, _fragmentIdIndex); buffer[_partialMsgTypeIndex] = (byte)message.MessageType; BufferHelper.CopyToIndex(message.Id.ToByteArray(), buffer, _msgIdIndex); if (partialPayloadSize > 0) { Buffer.BlockCopy(payload, payloadIndex, buffer, _partialPayloadIndex, partialPayloadSize); } var segment = new ArraySegment <byte>(buffer, 0, partialMsgSize); await _sendLock.WaitAsync(); try { await _transportChannel.SendAsync(segment, ct); } finally { _sendLock.Release(); } payloadIndex += partialPayloadSize; }while (!ct.IsCancellationRequested && payloadIndex < payloadSize); } finally { ArrayPool <byte> .Shared.Return(buffer); } }
public async Task SendMessage(Message message, CancellationToken ct) { var msgSize = _minMessageSize; var payloadSize = 0; var payload = message.Payload; if (payload != null) { payloadSize = payload.Length; msgSize += payloadSize; } var buffer = ArrayPool <byte> .Shared.Rent(msgSize); var locked = false; try { BufferHelper.CopyToIndex(BitConverter.GetBytes(msgSize), buffer, _sizeIndex); buffer[_messageTypeIndex] = (byte)message.MessageType; BufferHelper.CopyToIndex(message.Id.ToByteArray(), buffer, _idIndex); if (payloadSize > 0) { BufferHelper.CopyToIndex(payload, buffer, _payloadIndex); } var offset = 0; await _sendLock.WaitAsync(); locked = true; while (!ct.IsCancellationRequested && offset < msgSize) { var left = msgSize - offset; var next = Math.Min(_sendBufferSize, left); var segment = new ArraySegment <byte>(buffer, offset, next); await _transportChannel.SendAsync(segment, ct); offset += next; } } finally { if (locked) { _sendLock.Release(); } ArrayPool <byte> .Shared.Return(buffer); } }