PeerChannelFactory.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Channels
  5. {
  6. using System.Net;
  7. using System.Runtime;
  8. using System.ServiceModel;
  9. using System.Xml;
  10. interface IPeerFactory : ITransportFactorySettings
  11. {
  12. IPAddress ListenIPAddress { get; }
  13. int Port { get; }
  14. XmlDictionaryReaderQuotas ReaderQuotas { get; }
  15. PeerResolver Resolver { get; }
  16. PeerSecurityManager SecurityManager { get; }
  17. PeerNodeImplementation PrivatePeerNode { get; set; }
  18. long MaxBufferPoolSize { get; }
  19. }
  20. [ObsoleteAttribute ("PeerChannel feature is obsolete and will be removed in the future.", false)]
  21. sealed class PeerChannelFactory<TChannel> : TransportChannelFactory<TChannel>, IPeerFactory
  22. {
  23. // settings passed to PeerNode
  24. IPAddress listenIPAddress;
  25. int port;
  26. PeerResolver resolver;
  27. PeerSecurityManager securityManager;
  28. XmlDictionaryReaderQuotas readerQuotas;
  29. ISecurityCapabilities securityCapabilities;
  30. // use a private mesh (PeerNode) rather than creating/retrieving one from the registry.
  31. // used as a test hook to allow multiple PeerNode instances per app domain
  32. PeerNodeImplementation privatePeerNode;
  33. internal PeerChannelFactory(PeerTransportBindingElement bindingElement, BindingContext context,
  34. PeerResolver peerResolver)
  35. : base(bindingElement, context)
  36. {
  37. this.listenIPAddress = bindingElement.ListenIPAddress;
  38. this.port = bindingElement.Port;
  39. this.resolver = peerResolver;
  40. readerQuotas = new XmlDictionaryReaderQuotas();
  41. BinaryMessageEncodingBindingElement encoder = context.Binding.Elements.Find<BinaryMessageEncodingBindingElement>();
  42. if (encoder != null)
  43. encoder.ReaderQuotas.CopyTo(this.readerQuotas);
  44. else
  45. EncoderDefaults.ReaderQuotas.CopyTo(this.readerQuotas);
  46. this.securityManager = PeerSecurityManager.Create(bindingElement.Security, context, this.readerQuotas);
  47. this.securityCapabilities = bindingElement.GetProperty<ISecurityCapabilities>(context);
  48. }
  49. public IPAddress ListenIPAddress
  50. {
  51. get { return listenIPAddress; }
  52. }
  53. public int Port
  54. {
  55. get { return port; }
  56. }
  57. public XmlDictionaryReaderQuotas ReaderQuotas
  58. {
  59. get
  60. {
  61. return this.readerQuotas;
  62. }
  63. }
  64. public PeerResolver Resolver
  65. {
  66. get { return resolver; }
  67. }
  68. public override string Scheme
  69. {
  70. get { return PeerStrings.Scheme; }
  71. }
  72. public PeerNodeImplementation PrivatePeerNode
  73. {
  74. get { return privatePeerNode; }
  75. set { privatePeerNode = value; }
  76. }
  77. public PeerSecurityManager SecurityManager
  78. {
  79. get { return this.securityManager; }
  80. set { this.securityManager = value; }
  81. }
  82. public override T GetProperty<T>()
  83. {
  84. if (typeof(T) == typeof(PeerChannelFactory<TChannel>))
  85. {
  86. return (T)(object)this;
  87. }
  88. else if (typeof(T) == typeof(IPeerFactory))
  89. {
  90. return (T)(object)this;
  91. }
  92. else if (typeof(T) == typeof(PeerNodeImplementation))
  93. {
  94. return (T)(object)privatePeerNode;
  95. }
  96. else if (typeof(T) == typeof(ISecurityCapabilities))
  97. {
  98. return (T)(object)this.securityCapabilities;
  99. }
  100. return base.GetProperty<T>();
  101. }
  102. protected override void OnOpen(TimeSpan timeout)
  103. {
  104. }
  105. protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
  106. {
  107. return new CompletedAsyncResult(callback, state);
  108. }
  109. protected override void OnEndOpen(IAsyncResult result)
  110. {
  111. CompletedAsyncResult.End(result);
  112. }
  113. protected override TChannel OnCreateChannel(EndpointAddress to, Uri via)
  114. {
  115. base.ValidateScheme(via);
  116. PeerNodeImplementation peerNode = null;
  117. PeerNodeImplementation.Registration registration = null;
  118. // use the private PeerNode if it has been configured and matches the channel
  119. // otherwise have the channel look for one or create a new one
  120. if (privatePeerNode != null && via.Host == privatePeerNode.MeshId)
  121. {
  122. peerNode = privatePeerNode;
  123. }
  124. else
  125. {
  126. registration = new PeerNodeImplementation.Registration(via, this);
  127. }
  128. if (typeof(TChannel) == typeof(IOutputChannel))
  129. {
  130. return (TChannel)(object)new PeerOutputChannel(peerNode, registration, this, to, via, this.MessageVersion);
  131. }
  132. // typeof(TChannel) == typeof(IDuplexChannel)
  133. // 'to' is both the remote address and the local address
  134. PeerDuplexChannel duplexChannel = new PeerDuplexChannel(peerNode, registration, this, to, via);
  135. PeerMessageDispatcher<IDuplexChannel, PeerDuplexChannel>.PeerMessageQueueAdapter queueHandler = new PeerMessageDispatcher<IDuplexChannel, PeerDuplexChannel>.PeerMessageQueueAdapter(duplexChannel);
  136. PeerMessageDispatcher<IDuplexChannel, PeerDuplexChannel> dispatcher = new PeerMessageDispatcher<IDuplexChannel, PeerDuplexChannel>(queueHandler, duplexChannel.InnerNode, this, to, via);
  137. duplexChannel.Dispatcher = dispatcher;
  138. return (TChannel)(object)duplexChannel;
  139. }
  140. }
  141. }