//------------------------------------------------------------ // 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 : TransportChannelFactory, 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(); 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(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() { if (typeof(T) == typeof(PeerChannelFactory)) { 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(); } 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.PeerMessageQueueAdapter queueHandler = new PeerMessageDispatcher.PeerMessageQueueAdapter(duplexChannel); PeerMessageDispatcher dispatcher = new PeerMessageDispatcher(queueHandler, duplexChannel.InnerNode, this, to, via); duplexChannel.Dispatcher = dispatcher; return (TChannel)(object)duplexChannel; } } }