/// <summary> /// Send buffer /// </summary> /// <param name="buffer"></param> /// <param name="endpoint"></param> /// <param name="ct"></param> /// <returns></returns> public async override Task <int> SendAsync(ArraySegment <byte> buffer, SocketAddress endpoint, CancellationToken ct) { var sent = await SendBlock.SendAsync(Message.Create(null, null, null, DataMessage.Create(buffer, endpoint)), ct).ConfigureAwait(false); return(buffer.Count); }
/// <summary> /// Create send block /// </summary> /// <param name="maxSize">max buffer size for sending</param> protected virtual void CreateSendBlock(int maxSize) { var options = new ExecutionDataflowBlockOptions { NameFormat = "Send (in Link) Id={1}", EnsureOrdered = true, MaxMessagesPerTask = DataflowBlockOptions.Unbounded, SingleProducerConstrained = false, BoundedCapacity = 3 }; if (maxSize == 0) { _send = new BufferBlock <Message>(options); return; } _send = new TransformManyBlock <Message, Message>((message) => { if (message.TypeId != MessageContent.Data || ((DataMessage)message.Content).Payload.Length <= maxSize) { return(message.YieldReturn()); } // Split messages if needed using max size var data = message.Content as DataMessage; var segmentCount = data.Payload.Length / maxSize; var segmentSize = maxSize; if (data.Payload.Length % maxSize != 0) { // Distribute payload equally across all messages segmentCount++; segmentSize = (data.Payload.Length + segmentCount) / segmentCount; } // Create segment messages var segmentMessages = new Message[segmentCount]; for (int i = 0, offset = 0; i < segmentMessages.Length; i++, offset += segmentSize) { var segmentLength = Math.Min(data.Payload.Length - offset, segmentSize); var segment = new ArraySegment <byte>(data.Payload, offset, segmentLength); segmentMessages[i] = Message.Create(message.Source, message.Target, message.Proxy, DataMessage.Create(segment, null)); } return(segmentMessages); }, options); }