private void Initialize(Message message) { Exception exceptionToThrow; this.sendSockets = this.channel.GetSendSockets(message, out this.remoteEndpoint, out exceptionToThrow); if (exceptionToThrow != null) { throw FxTrace.Exception.AsError(exceptionToThrow); } this.IsMulticast = UdpUtility.IsMulticastAddress(this.remoteEndpoint.Address); if (this.channel.ShouldRetransmitMessage(this.IsMulticast)) { this.retransmissionEnabled = true; this.channel.RetransmitStarting(this.message.Headers.MessageId, this); this.retransmitTimer = new IOThreadTimer(onRetransmitMessage, this, false); this.retransmitIterator = this.channel.CreateRetransmitIterator(this.IsMulticast); } this.messageData = this.channel.EncodeMessage(message); }
protected override void OnSend(Message message, TimeSpan timeout) { if (message is NullMessage) { return; } TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); IPEndPoint remoteEndPoint; UdpSocket[] sendSockets; Exception exceptionToBeThrown; sendSockets = this.GetSendSockets(message, out remoteEndPoint, out exceptionToBeThrown); if (exceptionToBeThrown != null) { throw FxTrace.Exception.AsError(exceptionToBeThrown); } if (timeoutHelper.RemainingTime() <= TimeSpan.Zero) { throw FxTrace.Exception.AsError(new TimeoutException(SR.SendTimedOut(remoteEndPoint, timeout))); } bool returnBuffer = false; ArraySegment <byte> messageData = default(ArraySegment <byte>); bool sendingMulticast = UdpUtility.IsMulticastAddress(remoteEndPoint.Address); SynchronousRetransmissionHelper retransmitHelper = null; RetransmitIterator retransmitIterator = null; bool shouldRetransmit = this.ShouldRetransmitMessage(sendingMulticast); try { if (shouldRetransmit) { retransmitIterator = this.CreateRetransmitIterator(sendingMulticast); retransmitHelper = new SynchronousRetransmissionHelper(sendingMulticast); this.RetransmitStarting(message.Headers.MessageId, retransmitHelper); } messageData = this.EncodeMessage(message); returnBuffer = true; this.TransmitMessage(messageData, sendSockets, remoteEndPoint, timeoutHelper); if (shouldRetransmit) { while (retransmitIterator.MoveNext()) { // wait for currentDelay time, then retransmit if (retransmitIterator.CurrentDelay > 0) { retransmitHelper.Wait(retransmitIterator.CurrentDelay); } if (retransmitHelper.IsCanceled) { ThrowIfAborted(); return; } // since we only invoke the encoder once just before the initial send of the message // we need to handle logging the message in the retransmission case if (MessageLogger.LogMessagesAtTransportLevel) { UdpOutputChannel.LogMessage(ref message, messageData); } this.TransmitMessage(messageData, sendSockets, remoteEndPoint, timeoutHelper); } } } finally { if (returnBuffer) { this.BufferManager.ReturnBuffer(messageData.Array); } if (shouldRetransmit) { this.RetransmitStopping(message.Headers.MessageId); if (retransmitHelper != null) { retransmitHelper.Dispose(); } } } }