/// <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); }
/// <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); }
/// <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); } } }
/// <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(); } }
/// <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); } }