Ejemplo n.º 1
0
        /// <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);
        }