File: System\ServiceModel\Channels\PeerChannelFactory.cs
Project: ndp\cdf\src\WCF\ServiceModel\System.ServiceModel.csproj (System.ServiceModel)
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------
 
namespace System.ServiceModel.Channels
{
    using System.Net;
    using System.Runtime;
    using System.ServiceModel;
    using System.Xml;
 
    interface IPeerFactory : ITransportFactorySettings
    {
        IPAddress ListenIPAddress { get; }
        int Port { get; }
        XmlDictionaryReaderQuotas ReaderQuotas { get; }
        PeerResolver Resolver { get; }
        PeerSecurityManager SecurityManager { get; }
        PeerNodeImplementation PrivatePeerNode { get; set; }
        long MaxBufferPoolSize { get; }
    }
 
    [ObsoleteAttribute ("PeerChannel feature is obsolete and will be removed in the future.", false)]
    sealed class PeerChannelFactory<TChannel> : TransportChannelFactory<TChannel>, IPeerFactory
    {
        // settings passed to PeerNode
        IPAddress listenIPAddress;
        int port;
        PeerResolver resolver;
        PeerSecurityManager securityManager;
        XmlDictionaryReaderQuotas readerQuotas;
        ISecurityCapabilities securityCapabilities;
 
        // use a private mesh (PeerNode) rather than creating/retrieving one from the registry.
        // used as a test hook to allow multiple PeerNode instances per app domain
        PeerNodeImplementation privatePeerNode;
 
        internal PeerChannelFactory(PeerTransportBindingElement bindingElement, BindingContext context,
            PeerResolver peerResolver)
            : base(bindingElement, context)
        {
            this.listenIPAddress = bindingElement.ListenIPAddress;
            this.port = bindingElement.Port;
            this.resolver = peerResolver;
            readerQuotas = new XmlDictionaryReaderQuotas();
            BinaryMessageEncodingBindingElement encoder = context.Binding.Elements.Find<BinaryMessageEncodingBindingElement>();
            if (encoder != null)
                encoder.ReaderQuotas.CopyTo(this.readerQuotas);
            else
                EncoderDefaults.ReaderQuotas.CopyTo(this.readerQuotas);
            this.securityManager = PeerSecurityManager.Create(bindingElement.Security, context, this.readerQuotas);
            this.securityCapabilities = bindingElement.GetProperty<ISecurityCapabilities>(context);
        }
 
        public IPAddress ListenIPAddress
        {
            get { return listenIPAddress; }
        }
 
        public int Port
        {
            get { return port; }
        }
 
        public XmlDictionaryReaderQuotas ReaderQuotas
        {
            get
            {
                return this.readerQuotas;
            }
        }
 
        public PeerResolver Resolver
        {
            get { return resolver; }
        }
 
        public override string Scheme
        {
            get { return PeerStrings.Scheme; }
        }
 
        public PeerNodeImplementation PrivatePeerNode
        {
            get { return privatePeerNode; }
            set { privatePeerNode = value; }
        }
 
        public PeerSecurityManager SecurityManager
        {
            get { return this.securityManager; }
            set { this.securityManager = value; }
        }
 
        public override T GetProperty<T>()
        {
            if (typeof(T) == typeof(PeerChannelFactory<TChannel>))
            {
                return (T)(object)this;
            }
            else if (typeof(T) == typeof(IPeerFactory))
            {
                return (T)(object)this;
            }
            else if (typeof(T) == typeof(PeerNodeImplementation))
            {
                return (T)(object)privatePeerNode;
            }
            else if (typeof(T) == typeof(ISecurityCapabilities))
            {
                return (T)(object)this.securityCapabilities;
            }
 
            return base.GetProperty<T>();
        }
 
        protected override void OnOpen(TimeSpan timeout)
        {
        }
 
        protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
        {
            return new CompletedAsyncResult(callback, state);
        }
 
        protected override void OnEndOpen(IAsyncResult result)
        {
            CompletedAsyncResult.End(result);
        }
 
        protected override TChannel OnCreateChannel(EndpointAddress to, Uri via)
        {
            base.ValidateScheme(via);
 
            PeerNodeImplementation peerNode = null;
            PeerNodeImplementation.Registration registration = null;
 
            // use the private PeerNode if it has been configured and matches the channel
            // otherwise have the channel look for one or create a new one
            if (privatePeerNode != null && via.Host == privatePeerNode.MeshId)
            {
                peerNode = privatePeerNode;
            }
            else
            {
                registration = new PeerNodeImplementation.Registration(via, this);
            }
 
            if (typeof(TChannel) == typeof(IOutputChannel))
            {
                return (TChannel)(object)new PeerOutputChannel(peerNode, registration, this, to, via, this.MessageVersion);
            }
 
            // typeof(TChannel) == typeof(IDuplexChannel)
            // 'to' is both the remote address and the local address
            PeerDuplexChannel duplexChannel = new PeerDuplexChannel(peerNode, registration, this, to, via);
            PeerMessageDispatcher<IDuplexChannel, PeerDuplexChannel>.PeerMessageQueueAdapter queueHandler = new PeerMessageDispatcher<IDuplexChannel, PeerDuplexChannel>.PeerMessageQueueAdapter(duplexChannel);
            PeerMessageDispatcher<IDuplexChannel, PeerDuplexChannel> dispatcher = new PeerMessageDispatcher<IDuplexChannel, PeerDuplexChannel>(queueHandler, duplexChannel.InnerNode, this, to, via);
            duplexChannel.Dispatcher = dispatcher;
            return (TChannel)(object)duplexChannel;
        }
    }
}