PeerOutputChannel.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Channels
  5. {
  6. using System;
  7. using System.Diagnostics;
  8. using System.Runtime;
  9. using System.ServiceModel;
  10. using System.ServiceModel.Security;
  11. class PeerOutputChannel : TransportOutputChannel
  12. {
  13. PeerNode peerNode;
  14. Uri via;
  15. EndpointAddress to;
  16. SecurityProtocol securityProtocol;
  17. bool released;
  18. ChannelManagerBase channelManager;
  19. public PeerOutputChannel(PeerNodeImplementation peerNode, PeerNodeImplementation.Registration registration, ChannelManagerBase channelManager,
  20. EndpointAddress localAddress, Uri via, MessageVersion messageVersion)
  21. : base(channelManager, localAddress, via, false, messageVersion)
  22. {
  23. PeerNodeImplementation.ValidateVia(via);
  24. if (registration != null)
  25. {
  26. peerNode = PeerNodeImplementation.Get(via, registration);
  27. }
  28. this.peerNode = new PeerNode(peerNode);
  29. this.via = via;
  30. this.channelManager = channelManager;
  31. this.to = localAddress;
  32. }
  33. public override T GetProperty<T>()
  34. {
  35. if (typeof(T) == typeof(PeerNode))
  36. {
  37. return (T)(object)this.peerNode;
  38. }
  39. else if (typeof(T) == typeof(PeerNodeImplementation))
  40. {
  41. return (T)(object)this.peerNode.InnerNode;
  42. }
  43. else if (typeof(T) == typeof(IOnlineStatus))
  44. {
  45. return (T)(object)this.peerNode;
  46. }
  47. else if (typeof(T) == typeof(FaultConverter))
  48. {
  49. return (T)(object)FaultConverter.GetDefaultFaultConverter(MessageVersion.Soap12WSAddressing10);
  50. }
  51. return base.GetProperty<T>();
  52. }
  53. protected override void OnAbort()
  54. {
  55. if (this.State < CommunicationState.Closed)
  56. {
  57. try
  58. {
  59. this.peerNode.InnerNode.Abort();
  60. }
  61. catch (Exception e)
  62. {
  63. if (Fx.IsFatal(e)) throw;
  64. DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
  65. }
  66. }
  67. }
  68. protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
  69. {
  70. return this.peerNode.InnerNode.BeginClose(timeout, callback, state);
  71. }
  72. protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
  73. {
  74. IAsyncResult result = this.peerNode.InnerNode.BeginOpen(timeout, callback, state, true);
  75. return result;
  76. }
  77. protected override void OnClose(TimeSpan timeout)
  78. {
  79. this.peerNode.InnerNode.Close(timeout);
  80. }
  81. protected override void OnClosing()
  82. {
  83. base.OnClosing();
  84. ReleaseNode();
  85. }
  86. void ReleaseNode()
  87. {
  88. if (!this.released)
  89. {
  90. bool release = false;
  91. lock (ThisLock)
  92. {
  93. if (!this.released)
  94. {
  95. release = this.released = true;
  96. }
  97. }
  98. if (release && (this.peerNode != null))
  99. {
  100. this.peerNode.InnerNode.Release();
  101. }
  102. }
  103. }
  104. protected override void OnOpen(TimeSpan timeout)
  105. {
  106. this.peerNode.OnOpen();
  107. this.peerNode.InnerNode.Open(timeout, true);
  108. }
  109. protected override void OnFaulted()
  110. {
  111. base.OnFaulted();
  112. ReleaseNode();
  113. }
  114. protected override void OnEndClose(IAsyncResult result)
  115. {
  116. PeerNodeImplementation.EndClose(result);
  117. }
  118. protected override void OnEndOpen(IAsyncResult result)
  119. {
  120. PeerNodeImplementation.EndOpen(result);
  121. }
  122. protected override void OnSend(Message message, TimeSpan timeout)
  123. {
  124. EndSend(BeginSend(message, timeout, null, null));
  125. }
  126. protected override IAsyncResult OnBeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)
  127. {
  128. TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
  129. if (this.securityProtocol == null)
  130. {
  131. lock (ThisLock)
  132. {
  133. if (this.securityProtocol == null)
  134. {
  135. this.securityProtocol = ((IPeerFactory)channelManager).SecurityManager.CreateSecurityProtocol<IOutputChannel>(this.to, timeoutHelper.RemainingTime());
  136. }
  137. }
  138. }
  139. return this.peerNode.InnerNode.BeginSend(this, message, this.via, (ITransportFactorySettings)Manager, timeoutHelper.RemainingTime(), callback, state, this.securityProtocol);
  140. }
  141. protected override void OnEndSend(IAsyncResult result)
  142. {
  143. PeerNodeImplementation.EndSend(result);
  144. }
  145. protected override void AddHeadersTo(Message message)
  146. {
  147. this.RemoteAddress.ApplyTo(message);
  148. }
  149. }
  150. }