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