Пример #1
0
        /// <summary>
        /// Synchronously replies to the context request.
        /// </summary>
        /// <param name="context">The <see cref="LillTekRequestContext" /> context.</param>
        /// <param name="message">The reply <see cref="Message" />.</param>
        public void Reply(LillTekRequestContext context, Message message)
        {
            IAsyncResult ar;

            ar = BeginReply(context, message, null, null);
            EndReply(ar);
        }
Пример #2
0
        /// <summary>
        /// Intitiates an asynchronous operation to send a reply to the context request.
        /// </summary>
        /// <param name="context">The <see cref="LillTekRequestContext" /> context.</param>
        /// <param name="message">The reply <see cref="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 defined state (or <c>null</c>).</param>
        /// <returns>The <see cref="IAsyncResult" /> to be used to track the status of the operation.</returns>
        /// <remarks>
        /// <note>
        /// Every successful call to <see cref="BeginReply(LillTekRequestContext,Message,AsyncCallback,object)" /> must eventually be followed by
        /// a call to <see cref="EndReply" />.
        /// </note>
        /// </remarks>
        public IAsyncResult BeginReply(LillTekRequestContext context, Message message, AsyncCallback callback, object state)
        {
            AsyncResult arReply;

            // This operation is inherently asynchronous at the LillTek Messaging level
            // so we'll complete the operation immediately.

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

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

                replyMsg.Payload = new ArraySegment <byte>(ms.GetBuffer(), 0, (int)ms.Length);

                using (TimedLock.Lock(this))
                {
                    if (pendingRequests.ContainsKey(context.MsgRequestContext.SessionID))
                    {
                        pendingRequests.Remove(context.MsgRequestContext.SessionID);
                    }

                    context.MsgRequestContext.Reply(replyMsg);
                }
            }

            arReply = new AsyncResult(null, callback, state);
            arReply.Started(ServiceModelHelper.AsyncTrace);
            arReply.Notify();

            return(arReply);
        }
Пример #3
0
 /// <summary>
 /// Used internally by unit test to remove a request from the channel's
 /// pending requests table.
 /// </summary>
 /// <param name="ctx">The <see cref="LillTekRequestContext" />.</param>
 internal void RemovePendingRequest(LillTekRequestContext ctx)
 {
     using (TimedLock.Lock(this))
     {
         if (pendingRequests != null && pendingRequests.ContainsKey(ctx.MsgRequestContext.SessionID))
         {
             pendingRequests.Remove(ctx.MsgRequestContext.SessionID);
         }
     }
 }
Пример #4
0
        /// <summary>
        /// Closes the context.
        /// </summary>
        /// <param name="context">The <see cref="LillTekRequestContext" /> context.</param>
        void IReplyImplementation.Close(LillTekRequestContext context)
        {
            using (TimedLock.Lock(this))
            {
                if (pendingRequests.ContainsKey(context.MsgRequestContext.SessionID))
                {
                    pendingRequests.Remove(context.MsgRequestContext.SessionID);
                }

                context.MsgRequestContext.Close();
            }
        }
Пример #5
0
        /// <summary>
        /// Completes the asynchronous operation initiated by a <see cref="BeginTryReceiveRequest" /> call.
        /// </summary>
        /// <param name="result">The <see cref="IAsyncResult" /> instance returned by <see cref="BeginTryReceiveRequest" />.</param>
        /// <param name="context">Returns as the received <see cref="RequestContext" /> (or <c>null</c>).</param>
        /// <returns><c>true</c> if a request was received.</returns>
        public bool EndTryReceiveRequest(IAsyncResult result, out RequestContext context)
        {
            AsyncResult <RequestInfo, ReplyChannel> arReceive;
            RequestInfo requestInfo;

            context   = null;
            arReceive = result as AsyncResult <RequestInfo, ReplyChannel>;
            if (arReceive != null)
            {
                // Operation completed in BeginTryReceiveRequest() above.

                context = null;
                arReceive.Wait();
                try
                {
                    if (arReceive.Exception != null)
                    {
                        return(false);
                    }

                    requestInfo = arReceive.Result;
                    if (requestInfo == null)
                    {
                        return(true);
                    }

                    context = new LillTekRequestContext(requestInfo.Context, requestInfo.Message, this);
                    return(true);
                }
                finally
                {
                    arReceive.Dispose();
                }
            }

            if (listener.EndTryReceiveRequest(result, out requestInfo))
            {
                if (requestInfo == null)
                {
                    return(true);
                }

                using (TimedLock.Lock(this))
                    pendingRequests.Add(requestInfo.Context.SessionID, requestInfo.Context);

                context = new LillTekRequestContext(requestInfo.Context, requestInfo.Message, this);
                return(true);
            }
            else
            {
                return(false);
            }
        }