ServerReliableChannelBinder.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / ServerReliableChannelBinder.cs / 1 / ServerReliableChannelBinder.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.ServiceModel.Channels 
{
    using System; 
    using System.Diagnostics; 
    using System.ServiceModel;
    using System.ServiceModel.Diagnostics; 
    using System.ServiceModel.Dispatcher;
    using System.Collections.Generic;
    using System.ServiceModel.Security;
    using System.Threading; 

    abstract class ServerReliableChannelBinder : ReliableChannelBinder, 
        IServerReliableChannelBinder 
        where TChannel : class, IChannel
    { 
        static string addressedPropertyName = "MessageAddressedByBinderProperty";
        IChannelListener listener;
        static AsyncCallback onAcceptChannelComplete = DiagnosticUtility.ThunkAsyncCallback(
            new AsyncCallback(OnAcceptChannelCompleteStatic)); 
        EndpointAddress cachedLocalAddress;
        TChannel pendingChannel; 
        InterruptibleWaitObject pendingChannelEvent = new InterruptibleWaitObject(false, false); 
        EndpointAddress remoteAddress;
 
        protected ServerReliableChannelBinder(ChannelBuilder builder,
            EndpointAddress remoteAddress, MessageFilter filter, int priority, MaskingMode maskingMode,
            TolerateFaultsMode faultMode, TimeSpan defaultCloseTimeout,
            TimeSpan defaultSendTimeout) 
            : base(null, maskingMode, faultMode, defaultCloseTimeout, defaultSendTimeout)
        { 
            this.listener = builder.BuildChannelListener(filter, priority); 
            this.remoteAddress = remoteAddress;
        } 

        protected ServerReliableChannelBinder(TChannel channel, EndpointAddress cachedLocalAddress,
            EndpointAddress remoteAddress, MaskingMode maskingMode,
            TolerateFaultsMode faultMode, TimeSpan defaultCloseTimeout, 
            TimeSpan defaultSendTimeout)
            : base(channel, maskingMode, faultMode, defaultCloseTimeout, defaultSendTimeout) 
        { 
            this.cachedLocalAddress = cachedLocalAddress;
            this.remoteAddress = remoteAddress; 
        }

        protected override bool CanGetChannelForReceive
        { 
            get
            { 
                return true; 
            }
        } 

        public override EndpointAddress LocalAddress
        {
            get 
            {
                if (this.cachedLocalAddress != null) 
                { 
                    return this.cachedLocalAddress;
                } 
                else
                {
                    return this.GetInnerChannelLocalAddress();
                } 
            }
        } 
 
        protected override bool MustCloseChannel
        { 
            get
            {
                return this.MustOpenChannel || this.HasSession;
            } 
        }
 
        protected override bool MustOpenChannel 
        {
            get 
            {
                return this.listener != null;
            }
        } 

        public override EndpointAddress RemoteAddress 
        { 
            get
            { 
                return this.remoteAddress;
            }
        }
 
        void AddAddressedProperty(Message message)
        { 
            message.Properties.Add(addressedPropertyName, new object()); 
        }
 
        protected override void AddOutputHeaders(Message message)
        {
            if (this.GetAddressedProperty(message) == null)
            { 
                this.RemoteAddress.ApplyTo(message);
                this.AddAddressedProperty(message); 
            } 
        }
 
        public bool AddressResponse(Message request, Message response)
        {
            if (this.GetAddressedProperty(response) != null)
            { 
                DiagnosticUtility.DebugAssert("The binder can't address a response twice");
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
            } 

            try 
            {
                RequestReplyCorrelator.PrepareReply(response, request);
            }
            catch (MessageHeaderException exception) 
            {
                // ignore it - we don't need to correlate the reply if the MessageId header is bad 
                if (DiagnosticUtility.ShouldTraceInformation) 
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);
            } 

            bool sendResponse = true;
            try
            { 
                sendResponse = RequestReplyCorrelator.AddressReply(response, request);
            } 
            catch (MessageHeaderException exception) 
            {
                // ignore it - we don't need to address the reply if the addressing headers are bad 
                if (DiagnosticUtility.ShouldTraceInformation)
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);
            }
 
            if (sendResponse)
                this.AddAddressedProperty(response); 
 
            return sendResponse;
        } 

        protected override IAsyncResult BeginTryGetChannel(TimeSpan timeout,
            AsyncCallback callback, object state)
        { 
            return this.pendingChannelEvent.BeginTryWait(timeout, callback, state);
        } 
 
        public IAsyncResult BeginWaitForRequest(TimeSpan timeout, AsyncCallback callback,
            object state) 
        {
            if (this.DefaultMaskingMode != MaskingMode.None)
            {
                DiagnosticUtility.DebugAssert("This method was implemented only for the case where we do not mask exceptions."); 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false);
            } 
 
            if (this.ValidateInputOperation(timeout))
            { 
                return new WaitForRequestAsyncResult(this, timeout, callback, state);
            }
            else
            { 
                return new CompletedAsyncResult(callback, state);
            } 
        } 

        bool CompleteAcceptChannel(IAsyncResult result) 
        {
            TChannel channel = this.listener.EndAcceptChannel(result);

            if (channel == null) 
            {
                return false; 
            } 

            if (!this.UseNewChannel(channel)) 
            {
                channel.Abort();
            }
 
            return true;
        } 
 
        public static IServerReliableChannelBinder CreateBinder(ChannelBuilder builder,
            EndpointAddress remoteAddress, MessageFilter filter, int priority, 
            TolerateFaultsMode faultMode, TimeSpan defaultCloseTimeout,
            TimeSpan defaultSendTimeout)
        {
            Type type = typeof(TChannel); 

            if (type == typeof(IDuplexChannel)) 
            { 
                return new DuplexServerReliableChannelBinder(builder, remoteAddress, filter,
                    priority, MaskingMode.None, defaultCloseTimeout, defaultSendTimeout); 
            }
            else if (type == typeof(IDuplexSessionChannel))
            {
                return new DuplexSessionServerReliableChannelBinder(builder, remoteAddress, filter, 
                    priority, MaskingMode.None, faultMode, defaultCloseTimeout,
                    defaultSendTimeout); 
            } 
            else if (type == typeof(IReplyChannel))
            { 
                return new ReplyServerReliableChannelBinder(builder, remoteAddress, filter,
                    priority, MaskingMode.None, defaultCloseTimeout, defaultSendTimeout);
            }
            else if (type == typeof(IReplySessionChannel)) 
            {
                return new ReplySessionServerReliableChannelBinder(builder, remoteAddress, filter, 
                    priority, MaskingMode.None, faultMode, defaultCloseTimeout, 
                    defaultSendTimeout);
            } 
            else
            {
                DiagnosticUtility.DebugAssert("ServerReliableChannelBinder supports creation of IDuplexChannel, IDuplexSessionChannel, IReplyChannel, and IReplySessionChannel only.");
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
            }
        } 
 
        public static IServerReliableChannelBinder CreateBinder(TChannel channel,
            EndpointAddress cachedLocalAddress, EndpointAddress remoteAddress, 
            TolerateFaultsMode faultMode, TimeSpan defaultCloseTimeout,
            TimeSpan defaultSendTimeout)
        {
            Type type = typeof(TChannel); 

            if (type == typeof(IDuplexChannel)) 
            { 
                return new DuplexServerReliableChannelBinder((IDuplexChannel)channel,
                    cachedLocalAddress, remoteAddress, MaskingMode.All, defaultCloseTimeout, 
                    defaultSendTimeout);
            }
            else if (type == typeof(IDuplexSessionChannel))
            { 
                return new DuplexSessionServerReliableChannelBinder((IDuplexSessionChannel)channel,
                    cachedLocalAddress, remoteAddress, MaskingMode.All, faultMode, 
                    defaultCloseTimeout, defaultSendTimeout); 
            }
            else if (type == typeof(IReplyChannel)) 
            {
                return new ReplyServerReliableChannelBinder((IReplyChannel)channel,
                    cachedLocalAddress, remoteAddress, MaskingMode.All, defaultCloseTimeout,
                    defaultSendTimeout); 
            }
            else if (type == typeof(IReplySessionChannel)) 
            { 
                return new ReplySessionServerReliableChannelBinder((IReplySessionChannel)channel,
                    cachedLocalAddress, remoteAddress, MaskingMode.All, faultMode, 
                    defaultCloseTimeout, defaultSendTimeout);
            }
            else
            { 
                DiagnosticUtility.DebugAssert("ServerReliableChannelBinder supports creation of IDuplexChannel, IDuplexSessionChannel, IReplyChannel, and IReplySessionChannel only.");
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
            } 
        }
 
        protected override bool EndTryGetChannel(IAsyncResult result)
        {
            if (!this.pendingChannelEvent.EndTryWait(result))
                return false; 

            TChannel abortChannel = null; 
 
            lock (this.ThisLock)
            { 
                if (this.State != CommunicationState.Faulted &&
                    this.State != CommunicationState.Closing &&
                    this.State != CommunicationState.Closed)
                { 
                    if (!this.Synchronizer.SetChannel(this.pendingChannel))
                    { 
                        abortChannel = this.pendingChannel; 
                    }
 
                    this.pendingChannel = null;
                    this.pendingChannelEvent.Reset();
                }
            } 

            if (abortChannel != null) 
            { 
                abortChannel.Abort();
            } 

            return true;
        }
 
        public bool EndWaitForRequest(IAsyncResult result)
        { 
            WaitForRequestAsyncResult waitForRequestResult = result as WaitForRequestAsyncResult; 

            if (waitForRequestResult != null) 
            {
                return waitForRequestResult.End();
            }
            else 
            {
                CompletedAsyncResult.End(result); 
                return true; 
            }
        } 

        object GetAddressedProperty(Message message)
        {
            object property; 

            message.Properties.TryGetValue(addressedPropertyName, out property); 
            return property; 
        }
 
        protected abstract EndpointAddress GetInnerChannelLocalAddress();

        bool IsListenerExceptionNullOrHandleable(Exception e)
        { 
            if (e == null)
            { 
                return true; 
            }
 
            if (this.listener.State == CommunicationState.Faulted)
            {
                return false;
            } 

            return this.IsHandleable(e); 
        } 

        protected override void OnAbort() 
        {
            if (this.listener != null)
            {
                this.listener.Abort(); 
            }
        } 
 
        void OnAcceptChannelComplete(IAsyncResult result)
        { 
            Exception expectedException = null;
            Exception unexpectedException = null;
            bool gotChannel = false;
 
            try
            { 
                gotChannel = this.CompleteAcceptChannel(result); 
            }
            catch (Exception e) 
            {
                if (DiagnosticUtility.IsFatal(e))
                {
                    throw; 
                }
 
                if (this.IsHandleable(e)) 
                {
                    expectedException = e; 
                }
                else
                {
                    unexpectedException = e; 
                }
            } 
 
            if (gotChannel)
            { 
                this.StartAccepting();
            }
            else if (unexpectedException != null)
            { 
                this.Fault(unexpectedException);
            } 
            else if ((expectedException != null) 
                && (this.listener.State == CommunicationState.Opened))
            { 
                this.StartAccepting();
            }
            else if (this.listener.State == CommunicationState.Faulted)
            { 
                this.Fault(expectedException);
            } 
        } 

        static void OnAcceptChannelCompleteStatic(IAsyncResult result) 
        {
            if (!result.CompletedSynchronously)
            {
                ServerReliableChannelBinder binder = 
                    (ServerReliableChannelBinder)result.AsyncState;
 
                binder.OnAcceptChannelComplete(result); 
            }
        } 

        protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback,
            object state)
        { 
            if (this.listener != null)
            { 
                return this.listener.BeginClose(timeout, callback, state); 
            }
            else 
            {
                return new CompletedAsyncResult(callback, state);
            }
        } 

        protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, 
            object state) 
        {
            if (this.listener != null) 
            {
                return this.listener.BeginOpen(timeout, callback, state);
            }
            else 
            {
                return new CompletedAsyncResult(callback, state); 
            } 
        }
 
        protected abstract IAsyncResult OnBeginWaitForRequest(TChannel channel, TimeSpan timeout,
            AsyncCallback callback, object state);

        protected override void OnClose(TimeSpan timeout) 
        {
            if (this.listener != null) 
            { 
                this.listener.Close(timeout);
            } 
        }

        protected override void OnShutdown()
        { 
            TChannel channel = null;
 
            lock (this.ThisLock) 
            {
                channel = this.pendingChannel; 
                this.pendingChannel = null;
                this.pendingChannelEvent.Set();
            }
 
            if (channel != null)
                channel.Abort(); 
        } 

        protected abstract bool OnWaitForRequest(TChannel channel, TimeSpan timeout); 

        protected override void OnEndClose(IAsyncResult result)
        {
            if (this.listener != null) 
            {
                this.listener.EndClose(result); 
            } 
            else
            { 
                CompletedAsyncResult.End(result);
            }
        }
 
        protected override void OnEndOpen(IAsyncResult result)
        { 
            if (this.listener != null) 
            {
                this.listener.EndOpen(result); 
                this.StartAccepting();
            }
            else
            { 
                CompletedAsyncResult.End(result);
            } 
        } 

        protected abstract bool OnEndWaitForRequest(TChannel channel, IAsyncResult result); 

        protected override void OnOpen(TimeSpan timeout)
        {
            if (this.listener != null) 
            {
                this.listener.Open(timeout); 
                this.StartAccepting(); 
            }
        } 

        void StartAccepting()
        {
            Exception expectedException = null; 
            Exception unexpectedException = null;
 
            while (this.listener.State == CommunicationState.Opened) 
            {
                expectedException = null; 
                unexpectedException = null;

                try
                { 
                    IAsyncResult result = this.listener.BeginAcceptChannel(TimeSpan.MaxValue,
                        onAcceptChannelComplete, this); 
 
                    if (!result.CompletedSynchronously)
                    { 
                        return;
                    }
                    else if (!this.CompleteAcceptChannel(result))
                    { 
                        break;
                    } 
                } 
                catch (Exception e)
                { 
                    if (DiagnosticUtility.IsFatal(e))
                    {
                        throw;
                    } 

                    if (this.IsHandleable(e)) 
                    { 
                        expectedException = e;
                        continue; 
                    }
                    else
                    {
                        unexpectedException = e; 
                        break;
                    } 
                } 
            }
 
            if (unexpectedException != null)
            {
                this.Fault(unexpectedException);
            } 
            else if (this.listener.State == CommunicationState.Faulted)
            { 
                this.Fault(expectedException); 
            }
        } 

        protected override bool TryGetChannel(TimeSpan timeout)
        {
            if (!this.pendingChannelEvent.Wait(timeout)) 
                return false;
 
            TChannel abortChannel = null; 

            lock (this.ThisLock) 
            {
                if (this.State != CommunicationState.Faulted &&
                    this.State != CommunicationState.Closing &&
                    this.State != CommunicationState.Closed) 
                {
                    if (!this.Synchronizer.SetChannel(this.pendingChannel)) 
                    { 
                        abortChannel = this.pendingChannel;
                    } 

                    this.pendingChannel = null;
                    this.pendingChannelEvent.Reset();
                } 
            }
 
            if (abortChannel != null) 
            {
                abortChannel.Abort(); 
            }

            return true;
        } 

        public bool UseNewChannel(IChannel channel) 
        { 
            TChannel oldPendingChannel = null;
            TChannel oldBinderChannel = null; 

            lock (this.ThisLock)
            {
                if (!this.Synchronizer.TolerateFaults || 
                    this.State == CommunicationState.Faulted ||
                    this.State == CommunicationState.Closing || 
                    this.State == CommunicationState.Closed) 
                {
                    return false; 
                }
                else
                {
                    oldPendingChannel = this.pendingChannel; 
                    this.pendingChannel = (TChannel)channel;
                    oldBinderChannel = this.Synchronizer.AbortCurentChannel(); 
                } 
            }
 
            if (oldPendingChannel != null)
            {
                oldPendingChannel.Abort();
            } 

            this.pendingChannelEvent.Set(); 
 
            if (oldBinderChannel != null)
            { 
                oldBinderChannel.Abort();
            }

            return true; 
        }
 
        public bool WaitForRequest(TimeSpan timeout) 
        {
            if (this.DefaultMaskingMode != MaskingMode.None) 
            {
                DiagnosticUtility.DebugAssert("This method was implemented only for the case where we do not mask exceptions.");
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false);
            } 

            if (!this.ValidateInputOperation(timeout)) 
            { 
                return true;
            } 

            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);

            while (true) 
            {
                bool autoAborted = false; 
 
                try
                { 
                    TChannel channel;
                    bool success = !this.Synchronizer.TryGetChannelForInput(true, timeoutHelper.RemainingTime(),
                        out channel);
 
                    if (channel == null)
                    { 
                        return success; 
                    }
 
                    try
                    {
                        return this.OnWaitForRequest(channel, timeoutHelper.RemainingTime());
                    } 
                    finally
                    { 
                        autoAborted = this.Synchronizer.Aborting; 
                        this.Synchronizer.ReturnChannel();
                    } 
                }
                catch (Exception e)
                {
                    if (DiagnosticUtility.IsFatal(e)) 
                        throw;
 
                    if (!this.HandleException(e, this.DefaultMaskingMode, autoAborted)) 
                    {
                        throw; 
                    }
                    else
                    {
                        continue; 
                    }
                } 
 
            }
        } 

        abstract class DuplexServerReliableChannelBinder
            : ServerReliableChannelBinder
            where TDuplexChannel : class, IDuplexChannel 
        {
            protected DuplexServerReliableChannelBinder(ChannelBuilder builder, 
                EndpointAddress remoteAddress, MessageFilter filter, int priority, 
                MaskingMode maskingMode, TolerateFaultsMode faultMode,
                TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout) 
                : base(builder, remoteAddress, filter, priority, maskingMode, faultMode,
                defaultCloseTimeout, defaultSendTimeout)
            {
            } 

            protected DuplexServerReliableChannelBinder(TDuplexChannel channel, 
                EndpointAddress cachedLocalAddress, EndpointAddress remoteAddress, 
                MaskingMode maskingMode, TolerateFaultsMode faultMode,
                TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout) 
                : base(channel, cachedLocalAddress, remoteAddress, maskingMode, faultMode,
                defaultCloseTimeout, defaultSendTimeout)
            {
            } 

            public override bool CanSendAsynchronously 
            { 
                get
                { 
                    return true;
                }
            }
 
            protected override EndpointAddress GetInnerChannelLocalAddress()
            { 
                IDuplexChannel channel = this.Synchronizer.CurrentChannel; 
                EndpointAddress localAddress = (channel == null) ? null : channel.LocalAddress;
                return localAddress; 
            }

            protected override IAsyncResult OnBeginSend(TDuplexChannel channel, Message message,
                TimeSpan timeout, AsyncCallback callback, object state) 
            {
                return channel.BeginSend(message, timeout, callback, state); 
            } 

            protected override IAsyncResult OnBeginTryReceive(TDuplexChannel channel, 
                TimeSpan timeout, AsyncCallback callback, object state)
            {
                return channel.BeginTryReceive(timeout, callback, state);
            } 

            protected override IAsyncResult OnBeginWaitForRequest(TDuplexChannel channel, 
                TimeSpan timeout, AsyncCallback callback, object state) 
            {
                return channel.BeginWaitForMessage(timeout, callback, state); 
            }

            protected override void OnEndSend(TDuplexChannel channel, IAsyncResult result)
            { 
                channel.EndSend(result);
            } 
 
            protected override bool OnEndTryReceive(TDuplexChannel channel, IAsyncResult result,
                out RequestContext requestContext) 
            {
                Message message;
                bool success = channel.EndTryReceive(result, out message);
                if (success) 
                {
                    this.OnMessageReceived(message); 
                } 
                requestContext = this.WrapMessage(message);
                return success; 
            }

            protected override bool OnEndWaitForRequest(TDuplexChannel channel,
                IAsyncResult result) 
            {
                return channel.EndWaitForMessage(result); 
            } 

            protected abstract void OnMessageReceived(Message message); 

            protected override void OnSend(TDuplexChannel channel, Message message,
                TimeSpan timeout)
            { 
                channel.Send(message, timeout);
            } 
 
            protected override bool OnTryReceive(TDuplexChannel channel, TimeSpan timeout,
                out RequestContext requestContext) 
            {
                Message message;
                bool success = channel.TryReceive(timeout, out message);
                if (success) 
                {
                    this.OnMessageReceived(message); 
                } 
                requestContext = this.WrapMessage(message);
                return success; 
            }

            protected override bool OnWaitForRequest(TDuplexChannel channel, TimeSpan timeout)
            { 
                return channel.WaitForMessage(timeout);
            } 
 
        }
 
        sealed class DuplexServerReliableChannelBinder
            : DuplexServerReliableChannelBinder
        {
            public DuplexServerReliableChannelBinder(ChannelBuilder builder, 
                EndpointAddress remoteAddress, MessageFilter filter, int priority,
                MaskingMode maskingMode, TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout) 
                : base(builder, remoteAddress, filter, priority, maskingMode, 
                TolerateFaultsMode.Never, defaultCloseTimeout, defaultSendTimeout)
            { 
            }

            public DuplexServerReliableChannelBinder(IDuplexChannel channel,
                EndpointAddress cachedLocalAddress, EndpointAddress remoteAddress, 
                MaskingMode maskingMode, TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout)
                : base(channel, cachedLocalAddress, remoteAddress, maskingMode, TolerateFaultsMode.Never, 
                defaultCloseTimeout, defaultSendTimeout) 
            {
            } 

            public override bool HasSession
            {
                get 
                {
                    return false; 
                } 
            }
 
            public override ISession GetInnerSession()
            {
                return null;
            } 

            protected override bool HasSecuritySession(IDuplexChannel channel) 
            { 
                return false;
            } 

            protected override void OnMessageReceived(Message message)
            {
            } 
        }
 
        sealed class DuplexSessionServerReliableChannelBinder 
            : DuplexServerReliableChannelBinder
        { 
            public DuplexSessionServerReliableChannelBinder(ChannelBuilder builder,
                EndpointAddress remoteAddress, MessageFilter filter, int priority,
                MaskingMode maskingMode, TolerateFaultsMode faultMode,
                TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout) 
                : base(builder, remoteAddress, filter, priority, maskingMode, faultMode,
                defaultCloseTimeout, defaultSendTimeout) 
            { 
            }
 
            public DuplexSessionServerReliableChannelBinder(IDuplexSessionChannel channel,
                EndpointAddress cachedLocalAddress, EndpointAddress remoteAddress,
                MaskingMode maskingMode, TolerateFaultsMode faultMode,
                TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout) 
                : base(channel, cachedLocalAddress, remoteAddress, maskingMode, faultMode,
                defaultCloseTimeout, defaultSendTimeout) 
            { 
            }
 
            public override bool HasSession
            {
                get
                { 
                    return true;
                } 
            } 

            protected override IAsyncResult BeginCloseChannel(IDuplexSessionChannel channel, 
                TimeSpan timeout, AsyncCallback callback, object state)
            {
                return ReliableChannelBinderHelper.BeginCloseDuplexSessionChannel(this, channel,
                    timeout, callback, state); 
            }
 
            protected override void CloseChannel(IDuplexSessionChannel channel, TimeSpan timeout) 
            {
                ReliableChannelBinderHelper.CloseDuplexSessionChannel(this, channel, timeout); 
            }

            protected override void EndCloseChannel(IDuplexSessionChannel channel,
                IAsyncResult result) 
            {
                ReliableChannelBinderHelper.EndCloseDuplexSessionChannel(channel, result); 
            } 

            public override ISession GetInnerSession() 
            {
                return this.Synchronizer.CurrentChannel.Session;
            }
 
            protected override bool HasSecuritySession(IDuplexSessionChannel channel)
            { 
                return channel.Session is ISecuritySession; 
            }
 
            protected override void OnMessageReceived(Message message)
            {
                if (message == null)
                    this.Synchronizer.OnReadEof(); 
            }
        } 
 
        abstract class ReplyServerReliableChannelBinder
            : ServerReliableChannelBinder 
            where TReplyChannel : class, IReplyChannel
        {
            public ReplyServerReliableChannelBinder(ChannelBuilder builder,
                EndpointAddress remoteAddress, MessageFilter filter, int priority, 
                MaskingMode maskingMode, TolerateFaultsMode faultMode,
                TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout) 
                : base(builder, remoteAddress, filter, priority, maskingMode, faultMode, 
                defaultCloseTimeout, defaultSendTimeout)
            { 
            }

            public ReplyServerReliableChannelBinder(TReplyChannel channel,
                EndpointAddress cachedLocalAddress, EndpointAddress remoteAddress, 
                MaskingMode maskingMode, TolerateFaultsMode faultMode,
                TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout) 
                : base(channel, cachedLocalAddress, remoteAddress, maskingMode, faultMode, 
                defaultCloseTimeout, defaultSendTimeout)
            { 
            }

            public override bool CanSendAsynchronously
            { 
                get
                { 
                    return false; 
                }
            } 

            protected override EndpointAddress GetInnerChannelLocalAddress()
            {
                IReplyChannel channel = this.Synchronizer.CurrentChannel; 
                EndpointAddress localAddress = (channel == null) ? null : channel.LocalAddress;
                return localAddress; 
            } 

            protected override IAsyncResult OnBeginTryReceive(TReplyChannel channel, 
                TimeSpan timeout, AsyncCallback callback, object state)
            {
                return channel.BeginTryReceiveRequest(timeout, callback, state);
            } 

            protected override IAsyncResult OnBeginWaitForRequest(TReplyChannel channel, 
                TimeSpan timeout, AsyncCallback callback, object state) 
            {
                return channel.BeginWaitForRequest(timeout, callback, state); 
            }

            protected override bool OnEndTryReceive(TReplyChannel channel, IAsyncResult result,
                out RequestContext requestContext) 
            {
                bool success = channel.EndTryReceiveRequest(result, out requestContext); 
                if (success && (requestContext == null)) 
                {
                    this.OnReadNullMessage(); 
                }
                requestContext = this.WrapRequestContext(requestContext);
                return success;
            } 

            protected override bool OnEndWaitForRequest(TReplyChannel channel, IAsyncResult result) 
            { 
                return channel.EndWaitForRequest(result);
            } 

            protected virtual void OnReadNullMessage()
            {
            } 

            protected override bool OnTryReceive(TReplyChannel channel, TimeSpan timeout, 
                out RequestContext requestContext) 
            {
                bool success = channel.TryReceiveRequest(timeout, out requestContext); 
                if (success && (requestContext == null))
                {
                    this.OnReadNullMessage();
                } 
                requestContext = this.WrapRequestContext(requestContext);
                return success; 
            } 

            protected override bool OnWaitForRequest(TReplyChannel channel, TimeSpan timeout) 
            {
                return channel.WaitForRequest(timeout);
            }
        } 

        sealed class ReplyServerReliableChannelBinder 
            : ReplyServerReliableChannelBinder 
        {
            public ReplyServerReliableChannelBinder(ChannelBuilder builder, 
                EndpointAddress remoteAddress, MessageFilter filter, int priority,
                MaskingMode maskingMode, TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout)
                : base(builder, remoteAddress, filter, priority, maskingMode,
                TolerateFaultsMode.Never, defaultCloseTimeout, defaultSendTimeout) 
            {
            } 
 
            public ReplyServerReliableChannelBinder(IReplyChannel channel,
                EndpointAddress cachedLocalAddress, EndpointAddress remoteAddress, 
                MaskingMode maskingMode, TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout)
                : base(channel, cachedLocalAddress, remoteAddress, maskingMode,
                TolerateFaultsMode.Never, defaultCloseTimeout, defaultSendTimeout)
            { 
            }
 
            public override bool HasSession 
            {
                get 
                {
                    return false;
                }
            } 

            public override ISession GetInnerSession() 
            { 
                return null;
            } 

            protected override bool HasSecuritySession(IReplyChannel channel)
            {
                return false; 
            }
        } 
 
        sealed class ReplySessionServerReliableChannelBinder
            : ReplyServerReliableChannelBinder 
        {
            public ReplySessionServerReliableChannelBinder(ChannelBuilder builder,
                EndpointAddress remoteAddress, MessageFilter filter, int priority,
                MaskingMode maskingMode, TolerateFaultsMode faultMode, 
                TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout)
                : base(builder, remoteAddress, filter, priority, maskingMode, faultMode, 
                defaultCloseTimeout, defaultSendTimeout) 
            {
            } 

            public ReplySessionServerReliableChannelBinder(IReplySessionChannel channel,
                EndpointAddress cachedLocalAddress, EndpointAddress remoteAddress,
                MaskingMode maskingMode, TolerateFaultsMode faultMode, 
                TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout)
                : base(channel, cachedLocalAddress, remoteAddress, maskingMode, faultMode, 
                defaultCloseTimeout, defaultSendTimeout) 
            {
            } 

            public override bool HasSession
            {
                get 
                {
                    return true; 
                } 
            }
 
            protected override IAsyncResult BeginCloseChannel(IReplySessionChannel channel,
               TimeSpan timeout, AsyncCallback callback, object state)
            {
                return ReliableChannelBinderHelper.BeginCloseReplySessionChannel(this, channel, 
                    timeout, callback, state);
            } 
 
            protected override void CloseChannel(IReplySessionChannel channel, TimeSpan timeout)
            { 
                ReliableChannelBinderHelper.CloseReplySessionChannel(this, channel, timeout);
            }

            protected override void EndCloseChannel(IReplySessionChannel channel, 
                IAsyncResult result)
            { 
                ReliableChannelBinderHelper.EndCloseReplySessionChannel(channel, result); 
            }
 
            public override ISession GetInnerSession()
            {
                return this.Synchronizer.CurrentChannel.Session;
            } 

            protected override bool HasSecuritySession(IReplySessionChannel channel) 
            { 
                return channel.Session is ISecuritySession;
            } 

            protected override void OnReadNullMessage()
            {
                this.Synchronizer.OnReadEof(); 
            }
        } 
 
        sealed class WaitForRequestAsyncResult
            : InputAsyncResult> 
        {
            public WaitForRequestAsyncResult(ServerReliableChannelBinder binder,
                TimeSpan timeout, AsyncCallback callback, object state)
                : base(binder, true, timeout, binder.DefaultMaskingMode, callback, state) 
            {
                if (this.Start()) 
                    this.Complete(true); 
            }
 
            protected override IAsyncResult BeginInput(
                ServerReliableChannelBinder binder, TChannel channel, TimeSpan timeout,
                AsyncCallback callback, object state)
            { 
                return binder.OnBeginWaitForRequest(channel, timeout, callback, state);
            } 
 
            protected override bool EndInput(ServerReliableChannelBinder binder,
                TChannel channel, IAsyncResult result, out bool complete) 
            {
                complete = true;
                return binder.OnEndWaitForRequest(channel, result);
            } 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK