示例#1
0
        private bool closed = false;                        // True if the transaction has completed

        /// <summary>
        /// Constructs a <see cref="MsgRequestContext" /> for transactions that are not within a session.
        /// </summary>
        /// <param name="router">The <see cref="MsgRouter" />.</param>
        /// <param name="requestMsg">The request <see cref="Msg" />.</param>
        /// <exception cref="ArgumentException">Thrown if the message passed does not have all of the headers necessary to be a request.</exception>
        internal MsgRequestContext(MsgRouter router, Msg requestMsg)
        {
            if (router == null)
            {
                throw new ArgumentNullException("router");
            }

            if (requestMsg._FromEP == null)
            {
                throw new ArgumentException("Message cannot be a request: Null [_FromEP] header.", "requestMsg");
            }

            if (requestMsg._SessionID == Guid.Empty)
            {
                throw new ArgumentException("Message cannot be a request: Empty [_SessionID] header.", "requestMsg");
            }

            this.router    = router;
            this.session   = null;
            this.FromEP    = requestMsg._FromEP.Clone();
            this.SessionID = requestMsg._SessionID;
#if TRACE
            this.TraceName = requestMsg.GetType().Name;
#else
            this.TraceName = "(trace disabled)";
#endif
        }
示例#2
0
        /// <summary>
        /// Constructs a <see cref="MsgRequestContext" /> for transactions that are within a session.
        /// </summary>
        /// <param name="session">The <see cref="DuplexSession" />.</param>
        /// <param name="query">The request <see cref="Msg" />.</param>
        /// <exception cref="ArgumentException">Thrown if the message passed does not have all of the headers necessary to be a request.</exception>
        internal MsgRequestContext(DuplexSession session, Msg query)
        {
            if (session == null)
            {
                throw new ArgumentNullException("session");
            }

            if (query._FromEP == null)
            {
                throw new ArgumentException("Message cannot be a request: Null [_FromEP] header.", "requestMsg");
            }

            if (query._SessionID == Guid.Empty)
            {
                throw new ArgumentException("Message cannot be a request: Empty [_SessionID] header.", "requestMsg");
            }

            this.Header = query._ExtensionHeaders[MsgHeaderID.DuplexSession];
            if (this.Header == null)
            {
                throw new ArgumentException("Message is not a DuplexSession query.", "requestMsg");
            }

            this.router    = session.Router;
            this.session   = session;
            this.FromEP    = query._FromEP.Clone();
            this.SessionID = query._SessionID;
#if TRACE
            this.TraceName = query.GetType().Name;
#else
            this.TraceName = "(trace disabled)";
#endif
        }
示例#3
0
        /// <summary>
        /// Handles remote side closure of the underlying LillTek <see cref="DuplexSession" />.
        /// </summary>
        /// <param name="session">The <see cref="DuplexSession" />.</param>
        /// <param name="timeout">
        /// <c>true</c> if the session closed due to a keep-alive timeout,
        /// <c>false</c> if the remote side explicitly closed its side
        /// of the session.
        /// </param>
        private void OnSessionClose(DuplexSession session, bool timeout)
        {
            using (TimedLock.Lock(this))
            {
                // Terminate any pending Wait() operations with false.

                if (waitQueue != null)
                {
                    while (waitQueue.Count > 0)
                    {
                        waitQueue.Dequeue().Notify();
                    }
                }

                // Terminate any pending Receive() operations with null.

                if (receiveQueue != null)
                {
                    while (receiveQueue.Count > 0)
                    {
                        receiveQueue.Dequeue().Notify();
                    }
                }
            }
        }
示例#4
0
        //---------------------------------------------------------------------
        // DuplexSession event handlers

        /// <summary>
        /// Handles messages received on the underlying LillTek <see cref="DuplexSession" /> session.
        /// </summary>
        /// <param name="session">The <see cref="DuplexSession" />.</param>
        /// <param name="msg">The received LillTek message.</param>
        private void OnSessionReceive(DuplexSession session, Msg msg)
        {
            WcfEnvelopeMsg envelopeMsg = msg as WcfEnvelopeMsg;

            if (envelopeMsg == null)
            {
                return;     // Discard anything but WCF messages
            }
            Enqueue(listener.DecodeMessage(envelopeMsg));
        }
示例#5
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();
        }
示例#6
0
        private DuplexSession session;                                              // The underlying LillTek session

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="channelManager">The responsible channel manager.</param>
        /// <param name="localAddress">The local <see cref="EndpointAddress" /> this channel will use to receive requests.</param>
        /// <param name="sessionID">The globally unique session ID for this channel.</param>
        /// <param name="session">The underlying LillTek <see cref="DuplexSession" />.</param>
        public InputSessionChannel(ChannelManagerBase channelManager, EndpointAddress localAddress, string sessionID, DuplexSession session)
            : base(channelManager, sessionID)
        {
            this.maxReceiveQueueSize = ServiceModelHelper.MaxAcceptedMessages;      // $todo(jeff.lill): Hardcoding this
            this.bkTaskInterval      = ServiceModelHelper.DefaultBkTaskInterval;    //                   and this

            this.listener     = (InputSessionChannelListener)channelManager;
            this.localAddress = localAddress;
            this.msgQueue     = new LimitedQueue <Message>(maxReceiveQueueSize);
            this.waitQueue    = new QueueArray <AsyncResult <bool, object> >();
            this.receiveQueue = new QueueArray <AsyncResult <Message, object> >();
            this.session      = session;

            // Initialize the underlying LillTek session event handlers

            session.ReceiveEvent += new DuplexReceiveDelegate(OnSessionReceive);
            session.QueryEvent   += new DuplexQueryDelegate(OnSessionQuery);
            session.CloseEvent   += new DuplexCloseDelegate(OnSessionClose);
        }
示例#7
0
        /// <summary>
        /// Handles querues received on the underlying LillTek <see cref="DuplexSession" /> session.
        /// </summary>
        /// <param name="session">The <see cref="DuplexSession" />.</param>
        /// <param name="msg">The received LillTek query message.</param>
        /// <param name="isAsync">Returns as <c>true</c> if the query will be completed asynchronously.</param>
        private Msg OnSessionQuery(DuplexSession session, Msg msg, out bool isAsync)
        {
            // This channel type does not support queries.

            throw new NotImplementedException(string.Format("[{0}] does not support queries.", this.GetType().FullName));
        }
示例#8
0
 /// <summary>
 /// Handles remote side closure of the underlying LillTek <see cref="DuplexSession" />.
 /// </summary>
 /// <param name="session">The <see cref="DuplexSession" />.</param>
 /// <param name="timeout">
 /// <c>true</c> if the session closed due to a keep-alive timeout,
 /// <c>false</c> if the remote side explicitly closed its side
 /// of the session.
 /// </param>
 private void OnSessionClose(DuplexSession session, bool timeout)
 {
     // This is a NOP for this channel type.
 }
示例#9
0
        //---------------------------------------------------------------------
        // DuplexSession event handlers

        /// <summary>
        /// Handles messages received on the underlying LillTek <see cref="DuplexSession" /> session.
        /// </summary>
        /// <param name="session">The <see cref="DuplexSession" />.</param>
        /// <param name="msg">The received LillTek message.</param>
        private void OnSessionReceive(DuplexSession session, Msg msg)
        {
            throw new InvalidOperationException(string.Format("[{0}] does not support message reception.", this.GetType().FullName));
        }