Esempio n. 1
0
        /// <summary>
        /// Completes an asynchronous operation initiated by <see cref="BeginRequest(Message,AsyncCallback,object)" />
        /// or <see cref="BeginRequest(Message,TimeSpan,AsyncCallback,object)" />.
        /// </summary>
        /// <param name="result">The <see cref="IAsyncResult" /> instance returned by <b>BeginRequest()</b>.</param>
        /// <returns>The correlated response message.</returns>
        public Message EndRequest(IAsyncResult result)
        {
            try
            {
                WcfEnvelopeMsg replyMsg;

                replyMsg = (WcfEnvelopeMsg)ChannelHost.Router.EndQuery(result);

                if (!base.CanAcceptMessages)
                {
                    // This is a bit of a hack to simulate aborting pending
                    // requests when the channel is closed.

                    throw ServiceModelHelper.CreateObjectDisposedException(this);
                }

                // Decode the reply

                using (BlockStream bs = new BlockStream((Block)replyMsg.Payload))
                    return(encoder.ReadMessage(bs, ServiceModelHelper.MaxXmlHeaderSize));
            }
            catch (Exception e)
            {
                throw ServiceModelHelper.GetCommunicationException(e);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Initiates an asynchronous request/response transmission with a specific timeout.
        /// </summary>
        /// <param name="message">The request message.</param>
        /// <param name="timeout">The maximum time to wait for a response.</param>
        /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param>
        /// <param name="state">The application specific state (or <c>null</c>).</param>
        /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns>
        /// <remarks>
        /// <note>
        /// All successful calls to <see cref="BeginRequest(Message,TimeSpan,AsyncCallback,object)" /> must
        /// eventually be followed by a call to <see cref="EndRequest" />.
        /// </note>
        /// </remarks>
        public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
        {
            using (TimedLock.Lock(this))
            {
                ThrowIfDisposedOrNotOpen();
                ServiceModelHelper.ValidateTimeout(timeout);

                try
                {
                    using (MemoryStream ms = new MemoryStream(payloadEstimator.EstimateNextBufferSize()))
                    {
                        WcfEnvelopeMsg requestMsg = new WcfEnvelopeMsg();

                        encoder.WriteMessage(message, ms);
                        payloadEstimator.LastPayloadSize((int)ms.Length);

                        requestMsg.Payload = new ArraySegment <byte>(ms.GetBuffer(), 0, (int)ms.Length);
                        return(ChannelHost.Router.BeginQuery(ep, requestMsg, callback, state));
                    }
                }
                catch (Exception e)
                {
                    throw ServiceModelHelper.GetCommunicationException(e);
                }
            }
        }
Esempio n. 3
0
        private bool hostStarted;                                               // Indicates whether call to ChannelHost.Start() is current

        //---------------------------------------------------------------------
        // Implementation

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="context">The <see cref="BindingContext" /> holding the information necessary to construct the channel stack.</param>
        /// <exception cref="InvalidOperationException">Thrown if problems were found with the binding parameters.</exception>
        internal LillTekChannelListener(BindingContext context)
        {
            this.maxAcceptedChannels = ServiceModelHelper.MaxAcceptedChannels;      // $todo(jeff.lill): Hardcoded
            bkTaskInterval           = ServiceModelHelper.DefaultBkTaskInterval;    //                   This too

            this.context     = context;
            this.uri         = GetListenUri(context);
            this.ep          = ServiceModelHelper.ToMsgEP(uri);
            this.onBkTask    = new AsyncCallback(OnBkTask);
            this.sessionMode = false;
            this.hostStarted = false;

            // Initialize the message encoder factory from the binding context if
            // one was specified.  Use the binary message encoding factory otherwise.

            if (context.BindingParameters.FindAll <MessageEncodingBindingElement>().Count > 1)
            {
                throw new InvalidOperationException("Multiple MessageEncodingBindingElements were found in the BindingParameters of the BindingContext.");
            }

            MessageEncodingBindingElement element = context.BindingParameters.Find <MessageEncodingBindingElement>();

            if (element != null)
            {
                messageEncoderFactory = element.CreateMessageEncoderFactory();
            }
            else
            {
                messageEncoderFactory = new BinaryMessageEncodingBindingElement().CreateMessageEncoderFactory();
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Begins an asynchronous operation to receive a channel request (using a specified timeout).
        /// </summary>
        /// <param name="channel">The channel.</param>
        /// <param name="timeout">The <see cref="TimeSpan" /> value specifying the maximum time to wait for a request.</param>
        /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param>
        /// <param name="state">Application specific state (or <c>null</c>).</param>
        /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns>
        /// <remarks>
        /// <note>
        /// All calls to <see cref="BeginReceiveRequest" /> must eventually be followed by a call to <see cref="EndReceiveRequest" />.
        /// </note>
        /// </remarks>
        public IAsyncResult BeginReceiveRequest(ReplyChannel channel, TimeSpan timeout, AsyncCallback callback, object state)
        {
            AsyncResult <RequestInfo, ReplyChannel> arReceive;

            using (TimedLock.Lock(this))
            {
                timeout = ServiceModelHelper.ValidateTimeout(timeout);

                arReceive               = new AsyncResult <RequestInfo, ReplyChannel>(null, callback, state);
                arReceive.TTD           = SysTime.Now + timeout;
                arReceive.InternalState = channel;
                arReceive.Started(ServiceModelHelper.AsyncTrace);

                // Check to see if we already have a queued request.

                if (requestQueue.Count > 0)
                {
                    arReceive.Result = requestQueue.Dequeue();
                    arReceive.Notify();
                    return(arReceive);
                }

                // Otherwise queue the receive operation.

                receiveQueue.Enqueue(arReceive);
                return(arReceive);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Invoked during the transition of a communication object into the closed state.
        /// </summary>
        /// <remarks>
        /// The base class implementation calls <see cref="TerminatePendingOperations" /> and
        /// the associated channel manager's <see cref="ILillTekChannelManager.OnChannelCloseOrAbort" /> method.
        /// </remarks>
        protected override void OnClosed()
        {
            Exception e = ServiceModelHelper.CreateObjectDisposedException(this);

            TerminatePendingOperations(e);
            Cleanup();
            channelManager.OnChannelCloseOrAbort(this, e);
            base.OnClosed();
        }
Esempio n. 6
0
        /// <summary>
        /// Internal event handler.
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns></returns>
        protected override TChannel OnAcceptChannel(TimeSpan timeout)
        {
            IAsyncResult arAccept;

            timeout = ServiceModelHelper.ValidateTimeout(timeout);

            arAccept = BeginAcceptChannel(timeout, null, null);
            return(EndAcceptChannel(arAccept));
        }
Esempio n. 7
0
        /// <summary>
        /// Internal event handler.
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns></returns>
        protected override bool OnWaitForChannel(TimeSpan timeout)
        {
            IAsyncResult arWait;

            timeout = ServiceModelHelper.ValidateTimeout(timeout);

            arWait = BeginWaitForChannel(timeout, null, null);
            return(EndWaitForChannel(arWait));
        }
Esempio n. 8
0
        /// <summary>
        /// Synchronously sends a message-based request and then waits for the correlated message-based response,
        /// using a specific timeout value.
        /// </summary>
        /// <param name="message">The request message.</param>
        /// <param name="timeout">The maximum <see cref="TimeSpan" /> to wait.</param>
        /// <returns>The correlated response.</returns>
        /// <remarks>
        /// This override will use <paramref name="timeout" /> value passed
        /// as the maximum time to wait for a response.
        /// </remarks>
        public Message Request(Message message, TimeSpan timeout)
        {
            IAsyncResult arRequest;

            ServiceModelHelper.ValidateTimeout(timeout);

            arRequest = BeginRequest(message, timeout, null, null);
            return(EndRequest(arRequest));
        }
Esempio n. 9
0
        /// <summary>
        /// Inserts processing on a communication object after it transitions to the opening
        /// state due to the invocation of an asynchronous open operation.
        /// </summary>
        /// <param name="timeout">The <see cref="TimeSpan" /> that specifies how long the on open operation has to complete before timing out.</param>
        /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param>
        /// <param name="state">Application specific state (or <c>null</c>).</param>
        /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns>
        /// <remarks>
        /// The base class implementation initiates an asynchronous operation that will
        /// complete immediately on another thread.
        /// </remarks>
        protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
        {
            ServiceModelHelper.ValidateTimeout(timeout);

            session.ReceiveEvent += new DuplexReceiveDelegate(OnSessionReceive);
            session.QueryEvent   += new DuplexQueryDelegate(OnSessionQuery);
            session.CloseEvent   += new DuplexCloseDelegate(OnSessionClose);

            return(session.BeginConnect(ep, callback, state));
        }
Esempio n. 10
0
        /// <summary>
        /// Inserts processing on a communication object after it transitions to the opening
        /// state due to the invocation of an asynchronous open operation.
        /// </summary>
        /// <param name="timeout">The <see cref="TimeSpan" /> that specifies how long the on open operation has to complete before timing out.</param>
        /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param>
        /// <param name="state">Application specific state (or <c>null</c>).</param>
        /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns>
        /// <remarks>
        /// The base class implementation initiates an asynchronous operation that will
        /// complete immediately on another thread.
        /// </remarks>
        protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
        {
            AsyncResult arOpen;

            ServiceModelHelper.ValidateTimeout(timeout);

            arOpen = new AsyncResult(null, callback, state);
            arOpen.Started(ServiceModelHelper.AsyncTrace);
            arOpen.Notify();
            return(arOpen);
        }
Esempio n. 11
0
        /// <summary>
        /// Called by derived classes when a new channel is created.
        /// </summary>
        /// <param name="channel">The new channel.</param>
        public virtual void AddChannel(LillTekChannelBase channel)
        {
            using (TimedLock.Lock(this))
            {
                if (channels == null)
                {
                    throw ServiceModelHelper.CreateObjectDisposedException(this);
                }

                channels.Add(channel.ID, (TInternal)channel);
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Internal event handler.
        /// </summary>
        /// <param name="timeout"></param>
        /// <param name="callback"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
        {
            AsyncResult ar;

            Cleanup(ServiceModelHelper.CreateObjectDisposedException(this));
            timeout = ServiceModelHelper.ValidateTimeout(timeout);

            ar = new AsyncResult(null, callback, state);
            ar.Started(ServiceModelHelper.AsyncTrace);
            ar.Notify();
            return(ar);
        }
Esempio n. 13
0
        /// <summary>
        /// Inserts processing after a communication object transitions to the closing state
        /// due to the invocation of an asynchronous close operation.
        /// </summary>
        /// <param name="timeout">The <see cref="TimeSpan" /> that specifies how long the on close operation has to complete before timing out.</param>
        /// <param name="callback">The <see cref="AsyncCallback" /> delegate called when the operation completes (or <c>null</c>).</param>
        /// <param name="state">Application specific state (or <c>null</c>).</param>
        /// <returns>The <see cref="IAsyncResult" /> to be used to track the status of the operation.</returns>
        /// <remarks>
        /// The base class implementation initiates an asynchronous operation that will
        /// complete immediately on another thread.
        /// </remarks>
        protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
        {
            AsyncResult arClose;

            ServiceModelHelper.ValidateTimeout(timeout);
            session.Close();

            arClose = new AsyncResult(null, callback, state);
            arClose.Started(ServiceModelHelper.AsyncTrace);
            arClose.Notify();
            return(arClose);
        }
Esempio n. 14
0
        private PayloadSizeEstimator payloadEstimator;      // Used to estimate the buffer required to serialize
                                                            // the next message sent
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="channelManager">The responsible channel manager.</param>
        /// <param name="remoteAddress">The remote <see cref="EndpointAddress" />.</param>
        /// <param name="via">The first transport hop <see cref="Uri" />.</param>
        /// <param name="encoder">The <see cref="MessageEncoder" /> for serializing messages to the wire format.</param>
        public OutputChannel(ChannelManagerBase channelManager, EndpointAddress remoteAddress, Uri via, MessageEncoder encoder)
            : base(channelManager)
        {
            ServiceModelHelper.ValidateEP(remoteAddress.Uri);
            ServiceModelHelper.ValidateEP(via);

            this.remoteAddress    = remoteAddress;
            this.via              = via;
            this.encoder          = encoder;
            this.ep               = ServiceModelHelper.ToMsgEP(remoteAddress.Uri);
            this.payloadEstimator = new PayloadSizeEstimator(ServiceModelHelper.PayloadEstimatorSampleCount);
        }
Esempio n. 15
0
        /// <summary>
        /// Extracts the listening URI from a binding context.
        /// </summary>
        /// <param name="context">The <see cref="BindingContext" />.</param>
        /// <returns>The <see cref="Uri" />.</returns>
        /// <exception cref="ArgumentNullException">Thrown if BindingContext.ListenUriBaseAddress is not specified.</exception>
        /// <exception cref="ArgumentException">Thrown if the URI does not have a valid LillTek URI scheme.</exception>
        protected Uri GetListenUri(BindingContext context)
        {
            Uri    uri;
            Uri    baseAddress;
            string relativeAddress;

            baseAddress     = context.ListenUriBaseAddress;
            relativeAddress = context.ListenUriRelativeAddress;

            if (baseAddress == null)
            {
                if (context.ListenUriMode == ListenUriMode.Unique)
                {
                    baseAddress = ServiceModelHelper.CreateUniqueUri();
                }
                else
                {
                    throw new ArgumentNullException("BindingContext.ListenUriBaseAddress");
                }
            }

            if (string.IsNullOrWhiteSpace(relativeAddress))
            {
                uri = baseAddress;
            }
            else
            {
                UriBuilder ub = new UriBuilder(baseAddress);

                if (!ub.Path.EndsWith("/"))
                {
                    ub.Path += "/";
                }

                uri = new Uri(ub.Uri, relativeAddress);
            }

            // Verify that the URI scheme is a valid LillTek scheme.

            switch (uri.Scheme.ToLowerInvariant())
            {
            case "lilltek.logical":
            case "lilltek.abstract":

                return(uri);        // OK

            default:

                throw new ArgumentException(string.Format("Invalid LillTek Messaging WCF Transport scheme [{0}].", uri.Scheme), "BindingContext.ListenUriBaseAddress");
            }
        }
Esempio n. 16
0
 /// <summary>
 /// Decodes the WCF <see cref="Message" /> encapsulated within a LillTek <see cref="WcfEnvelopeMsg" />.
 /// </summary>
 /// <param name="msg">The LillTek message.</param>
 /// <returns>The WCF <see cref="Message" />.</returns>
 /// <exception cref="CommunicationException">Thrown if the message could not be decoded.</exception>
 public Message DecodeMessage(WcfEnvelopeMsg msg)
 {
     using (BlockStream bs = new BlockStream((Block)msg.Payload))
     {
         try
         {
             return(messageEncoderFactory.Encoder.ReadMessage(bs, ServiceModelHelper.MaxXmlHeaderSize));
         }
         catch (Exception e)
         {
             throw ServiceModelHelper.GetCommunicationException(e);
         }
     }
 }
Esempio n. 17
0
        /// <summary>
        /// Completes an asynchronous operation initiated by one of the <b>BeginSend()</b> overrides.
        /// </summary>
        /// <param name="result">The <see cref="IAsyncResult" /> instance returned by <b>BeginSend()</b>.</param>
        public void EndSend(IAsyncResult result)
        {
            AsyncResult arSend = (AsyncResult)result;

            arSend.Wait();
            try
            {
                if (arSend.Exception != null)
                {
                    throw ServiceModelHelper.GetCommunicationException(arSend.Exception);
                }
            }
            finally
            {
                arSend.Dispose();
            }
        }
Esempio n. 18
0
        /// <summary>
        /// Initiates an asynchronous attempt to receive a message within the
        /// specified period of time, where a boolean will ultimately be returned
        /// indicating success or failure rather than throwning an exception if
        /// an error is encountered.
        /// </summary>
        /// <param name="timeout">The maximum <see cref="TimeSpan" /> to wait for the message.</param>
        /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param>
        /// <param name="state">Application specific state (or <c>null</c>).</param>
        /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns>
        /// <remarks>
        /// All successful calls to <see cref="BeginTryReceive" /> must eventually be followed by a
        /// call to <see cref="EndTryReceive" />.
        /// </remarks>
        public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
        {
            AsyncResult <Message, object> arReceive;

            using (TimedLock.Lock(this))
            {
                timeout = ServiceModelHelper.ValidateTimeout(timeout);

                arReceive     = new AsyncResult <Message, object>(null, callback, state);
                arReceive.TTD = SysTime.Now + timeout;
                arReceive.Started(ServiceModelHelper.AsyncTrace);

                // Non-open channels always return true (message=null)

                if (base.State != CommunicationState.Opened)
                {
                    arReceive.Result = null;
                    arReceive.Notify();
                    return(arReceive);
                }

                // Check to see if we already have a queued message.

                if (msgQueue.Count > 0)
                {
                    arReceive.Result = msgQueue.Dequeue();
                    arReceive.Notify();
                    return(arReceive);
                }

                // Setup to return null if the remote side of the connection
                // has been closed.

                if (!session.IsConnected)
                {
                    arReceive.Notify();
                    return(arReceive);
                }

                // Otherwise queue the receive operation.

                receiveQueue.Enqueue(arReceive);
                return(arReceive);
            }
        }
Esempio n. 19
0
        /// <summary>
        /// Begins an asynchronous operation to wait for a specified period of time for a message to be received
        /// or queued internally by the channel.
        /// </summary>
        /// <param name="timeout">The maximum <see cref="TimeSpan" /> to wait.</param>
        /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param>
        /// <param name="state">Application specific state (or <c>null</c>).</param>
        /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns>
        /// <remarks>
        /// All successful calls to <see cref="BeginWaitForMessage" /> must eventually be followed by a call to <see cref="EndWaitForMessage" />.
        /// </remarks>
        public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state)
        {
            AsyncResult <bool, object> arWait;

            using (TimedLock.Lock(this))
            {
                timeout = ServiceModelHelper.ValidateTimeout(timeout);

                arWait     = new AsyncResult <bool, object>(null, callback, state);
                arWait.TTD = SysTime.Now + timeout;
                arWait.Started(ServiceModelHelper.AsyncTrace);

                // Non-open channels always return false

                if (base.State != CommunicationState.Opened)
                {
                    arWait.Result = false;
                    arWait.Notify();
                    return(arWait);
                }

                // Check to see if we already have a queued message.

                if (msgQueue.Count > 0)
                {
                    arWait.Result = true;
                    arWait.Notify();
                    return(arWait);
                }

                // Setup to return false if the remote side of the session
                // has been closed.

                if (!session.IsConnected)
                {
                    arWait.Notify();
                    return(arWait);
                }

                // Otherwise queue the wait operation.

                waitQueue.Enqueue(arWait);
                return(arWait);
            }
        }
Esempio n. 20
0
        private DuplexSession session;                      // Underlying LillTek Messaging session

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="channelManager">The responsible channel manager.</param>
        /// <param name="remoteAddress">The remote <see cref="EndpointAddress" />.</param>
        /// <param name="via">The first transport hop <see cref="Uri" />.</param>
        /// <param name="encoder">The <see cref="MessageEncoder" /> for serializing messages to the wire format.</param>
        public OutputSessionChannel(ChannelManagerBase channelManager, EndpointAddress remoteAddress, Uri via, MessageEncoder encoder)
            : base(channelManager)
        {
            ServiceModelHelper.ValidateEP(remoteAddress.Uri);
            ServiceModelHelper.ValidateEP(via);

            this.ep = ServiceModelHelper.ToMsgEP(remoteAddress.Uri);
            if (ep.Broadcast)
            {
                throw new ArgumentException("Sessionful channels cannot accept broadcast endpoints.", "remoteAddress");
            }

            this.remoteAddress    = remoteAddress;
            this.via              = via;
            this.encoder          = encoder;
            this.payloadEstimator = new PayloadSizeEstimator(ServiceModelHelper.PayloadEstimatorSampleCount);
            this.session          = ChannelHost.Router.CreateDuplexSession();
        }
Esempio n. 21
0
        public void ServiceModelHelper_ValidateTimeout()
        {
            TimeSpan timeout;

            ServiceModelHelper.ValidateTimeout(TimeSpan.Zero);
            ServiceModelHelper.ValidateTimeout(TimeSpan.FromMinutes(100));

            try
            {
                ServiceModelHelper.ValidateTimeout(TimeSpan.FromMinutes(-100));
                Assert.Fail("Expected an ArgumentException");
            }
            catch (ArgumentException)
            {
            }

            timeout = ServiceModelHelper.ValidateTimeout(TimeSpan.MaxValue);
            Assert.IsTrue(SysTime.Now + timeout < DateTime.MaxValue);
        }
Esempio n. 22
0
        /// <summary>
        /// Completes an asynchronous message receive operation.
        /// </summary>
        /// <param name="result">The <see cref="IAsyncResult" /> returned by one of the <b>BeginReceive()</b> overrides.</param>
        /// <returns>The <see cref="Message" /> received or <c>null</c> if the remote side of the session has been closed.</returns>
        public Message EndReceive(IAsyncResult result)
        {
            AsyncResult <Message, object> arReceive = (AsyncResult <Message, object>)result;

            arReceive.Wait();
            try
            {
                if (arReceive.Exception != null)
                {
                    throw ServiceModelHelper.GetCommunicationException(arReceive.Exception);
                }

                return(arReceive.Result);
            }
            finally
            {
                arReceive.Dispose();
            }
        }
Esempio n. 23
0
        /// <summary>
        /// Completes an asynchronous channel message receive operation.
        /// </summary>
        /// <param name="result">The <see cref="IAsyncResult" /> returned by <see cref="BeginReceive" />.</param>
        /// <returns>The <see cref="Message" /> received.</returns>
        public Message EndReceive(IAsyncResult result)
        {
            AsyncResult <Message, InputChannel> arReceive = (AsyncResult <Message, InputChannel>)result;

            Assertion.Test(arReceive.InternalState != null, "InternalState should have been set to the channel.");
            arReceive.Wait();
            try
            {
                if (arReceive.Exception != null)
                {
                    throw ServiceModelHelper.GetCommunicationException(arReceive.Exception);
                }

                return(arReceive.Result);
            }
            finally
            {
                arReceive.Dispose();
            }
        }
Esempio n. 24
0
        /// <summary>
        /// Synchronously sends a message on the output channel.
        /// </summary>
        /// <param name="message">The <see cref="Message" />.</param>
        /// <remarks>
        /// <note>
        /// This method does not guarantee delivery of the message.
        /// Messages can be silently dropped for reasons including lack of buffer
        /// space, network congestion, unavailable remote endpoint, etc.
        /// </note>
        /// </remarks>
        public void Send(Message message)
        {
            try
            {
                using (MemoryStream ms = new MemoryStream(payloadEstimator.EstimateNextBufferSize()))
                {
                    WcfEnvelopeMsg envelopeMsg = new WcfEnvelopeMsg();

                    encoder.WriteMessage(message, ms);
                    payloadEstimator.LastPayloadSize((int)ms.Length);

                    envelopeMsg.Payload = new ArraySegment <byte>(ms.GetBuffer(), 0, (int)ms.Length);
                    ChannelHost.Router.SendTo(ep, envelopeMsg);
                }
            }
            catch (Exception e)
            {
                throw ServiceModelHelper.GetCommunicationException(e);
            }
        }
Esempio n. 25
0
        public void ServiceModelHelper_ValidateEP()
        {
            ServiceModelHelper.ValidateEP(new Uri("lilltek.logical://test"));
            ServiceModelHelper.ValidateEP(new Uri("lilltek.abstract://test"));

            try
            {
                ServiceModelHelper.ValidateEP(new Uri("lilltek.physical://test"));
                Assert.Fail("Expected an ArgumentException");
            }
            catch (ArgumentException)
            {
            }

            try
            {
                ServiceModelHelper.ValidateEP(new Uri("http://test"));
                Assert.Fail("Expected an ArgumentException");
            }
            catch (ArgumentException)
            {
            }

            try
            {
                ServiceModelHelper.ValidateEP(new Uri("lilltek.logical://test:80"));
                Assert.Fail("Expected an ArgumentException");
            }
            catch (ArgumentException)
            {
            }

            try
            {
                ServiceModelHelper.ValidateEP(new Uri("lilltek.abstract://test:80"));
                Assert.Fail("Expected an ArgumentException");
            }
            catch (ArgumentException)
            {
            }
        }
Esempio n. 26
0
        /// <summary>
        /// Begins an asynchronous operation to wait for a specified period of time for a message to be received
        /// for a channel.
        /// </summary>
        /// <param name="channel">The channel.</param>
        /// <param name="timeout">The maximum <see cref="TimeSpan" /> to wait.</param>
        /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param>
        /// <param name="state">Application specific state (or <c>null</c>).</param>
        /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns>
        /// <remarks>
        /// All successful calls to <see cref="BeginWaitForMessage" /> must eventually be followed by a call to <see cref="EndWaitForMessage" />.
        /// </remarks>
        public IAsyncResult BeginWaitForMessage(InputChannel channel, TimeSpan timeout, AsyncCallback callback, object state)
        {
            AsyncResult <bool, InputChannel> arWait;

            using (TimedLock.Lock(this))
            {
                timeout = ServiceModelHelper.ValidateTimeout(timeout);

                arWait               = new AsyncResult <bool, InputChannel>(null, callback, state);
                arWait.TTD           = SysTime.Now + timeout;
                arWait.InternalState = channel;
                arWait.Started(ServiceModelHelper.AsyncTrace);

                // Non-open channels always return false.

                if (base.State != CommunicationState.Opened)
                {
                    arWait.Notify();
                    return(arWait);
                }

                // If we already have a queued message, dequeue it and add it to the
                // channel's message queue, so a subsequent call Receive() on the channel
                // will be assured to succeed.  Then notify that the operation is complete.

                if (msgQueue.Count > 0)
                {
                    channel.Enqueue(msgQueue.Dequeue());

                    arWait.Result = true;
                    arWait.Notify();
                    return(arWait);
                }

                // Otherwise queue the wait operation.

                waitQueue.Enqueue(arWait);
                return(arWait);
            }
        }
Esempio n. 27
0
        /// <summary>
        /// Begins an asynchronous operation to wait for a specified period of time for a message to be received
        /// or queued internally by the channel.
        /// </summary>
        /// <param name="timeout">The maximum <see cref="TimeSpan" /> to wait.</param>
        /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param>
        /// <param name="state">Application specific state (or <c>null</c>).</param>
        /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns>
        /// <remarks>
        /// All successful calls to <see cref="BeginWaitForMessage" /> must eventually be followed by a call to <see cref="EndWaitForMessage" />.
        /// </remarks>
        public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state)
        {
            using (TimedLock.Lock(this))
            {
                // Non-open channels always return false.

                if (base.State != CommunicationState.Opened)
                {
                    AsyncResult <bool, InputChannel> arWait;         // Note that TInternal==InputChannel.  This is used below in EndWaitForMessage()
                                                                     // to distinguish between IAsyncResults returned by this class and those
                                                                     // returned by the listener.

                    arWait        = new AsyncResult <bool, InputChannel>(null, callback, state);
                    arWait.Result = false;
                    arWait.Started(ServiceModelHelper.AsyncTrace);
                    arWait.Notify();
                    return(arWait);
                }

                // If the channel already has a message queued, then setup to return it.

                if (msgQueue.Count > 0)
                {
                    AsyncResult <bool, InputChannel> arWait;         // Note that TInternal==InputChannel.  This is used below in EndWaitForMessage()
                                                                     // to distinguish between IAsyncResults returned by this class and those
                                                                     // returned by the listener.

                    arWait        = new AsyncResult <bool, InputChannel>(null, callback, state);
                    arWait.Result = true;
                    arWait.Started(ServiceModelHelper.AsyncTrace);
                    arWait.Notify();
                    return(arWait);
                }
            }

            timeout = ServiceModelHelper.ValidateTimeout(timeout);
            return(listener.BeginWaitForMessage(this, timeout, callback, state));
        }
Esempio n. 28
0
        /// <summary>
        /// Internal event handler.
        /// </summary>
        /// <param name="timeout"></param>
        /// <param name="callback"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        protected override IAsyncResult OnBeginWaitForChannel(TimeSpan timeout, AsyncCallback callback, object state)
        {
            AsyncResult <bool, object> arWait;

            arWait     = new AsyncResult <bool, object>(null, callback, state);
            arWait.TTD = SysTime.Now + ServiceModelHelper.ValidateTimeout(timeout);
            arWait.Started(ServiceModelHelper.AsyncTrace);

            using (TimedLock.Lock(this))
            {
                if (channelQueue.Count > 0)
                {
                    arWait.Result = true;
                    arWait.Notify();
                }
                else
                {
                    // Give the derived class a chance to accept a channel

                    TInternal acceptChannel;

                    acceptChannel = GetAcceptChannel();
                    if (acceptChannel != null)
                    {
                        channelQueue.Enqueue(acceptChannel);
                        arWait.Result = true;
                        arWait.Notify();
                    }
                    else
                    {
                        waitQueue.Enqueue(arWait);
                    }
                }
            }

            return(arWait);
        }
Esempio n. 29
0
        /// <summary>
        /// Begins an asynchronous operation to receive a channel message (using a specified timeout).
        /// </summary>
        /// <param name="channel">The channel.</param>
        /// <param name="timeout">The <see cref="TimeSpan" /> value specifying the maximum time to wait for a message.</param>
        /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param>
        /// <param name="state">Application specific state (or <c>null</c>).</param>
        /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns>
        /// <remarks>
        /// <note>
        /// All calls to <see cref="BeginReceive" /> must eventually be followed by a call to <see cref="EndReceive" />.
        /// </note>
        /// </remarks>
        public IAsyncResult BeginReceive(InputChannel channel, TimeSpan timeout, AsyncCallback callback, object state)
        {
            AsyncResult <Message, InputChannel> arReceive;

            using (TimedLock.Lock(this))
            {
                timeout = ServiceModelHelper.ValidateTimeout(timeout);

                arReceive               = new AsyncResult <Message, InputChannel>(null, callback, state);
                arReceive.TTD           = SysTime.Now + timeout;
                arReceive.InternalState = channel;
                arReceive.Started(ServiceModelHelper.AsyncTrace);

                // Non-open channels always return null.

                if (base.State != CommunicationState.Opened)
                {
                    arReceive.Result = null;
                    arReceive.Notify();
                    return(arReceive);
                }

                // Check to see if we already have a queued message.

                if (msgQueue.Count > 0)
                {
                    arReceive.Result = msgQueue.Dequeue();
                    arReceive.Notify();
                    return(arReceive);
                }

                // Otherwise queue the receive operation.

                receiveQueue.Enqueue(arReceive);
                return(arReceive);
            }
        }
Esempio n. 30
0
 /// <summary>
 /// Internal event handler.
 /// </summary>
 /// <param name="timeout"></param>
 protected override void OnClose(TimeSpan timeout)
 {
     Cleanup(ServiceModelHelper.CreateObjectDisposedException(this));
 }