PeerInputChannel.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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.Diagnostics;
  11. class PeerInputChannel : InputChannel
  12. {
  13. EndpointAddress to;
  14. Uri via;
  15. PeerNode peerNode;
  16. bool released = false;
  17. public PeerInputChannel(PeerNodeImplementation peerNode, PeerNodeImplementation.Registration registration, ChannelManagerBase channelManager,
  18. EndpointAddress localAddress, Uri via)
  19. : base(channelManager, localAddress)
  20. {
  21. PeerNodeImplementation.ValidateVia(via);
  22. if (registration != null)
  23. {
  24. peerNode = PeerNodeImplementation.Get(via, registration);
  25. }
  26. this.peerNode = new PeerNode(peerNode);
  27. this.to = localAddress;
  28. this.via = via;
  29. }
  30. public override T GetProperty<T>()
  31. {
  32. if (typeof(T) == typeof(PeerNode))
  33. {
  34. return (T)(object)this.peerNode;
  35. }
  36. else if (typeof(T) == typeof(PeerNodeImplementation))
  37. {
  38. return (T)(object)this.peerNode.InnerNode;
  39. }
  40. else if (typeof(T) == typeof(IOnlineStatus))
  41. {
  42. return (T)(object)this.peerNode;
  43. }
  44. else if (typeof(T) == typeof(FaultConverter))
  45. {
  46. return (T)(object)FaultConverter.GetDefaultFaultConverter(MessageVersion.Soap12WSAddressing10);
  47. }
  48. return base.GetProperty<T>();
  49. }
  50. protected override void OnAbort()
  51. {
  52. base.OnAbort();
  53. if (this.State < CommunicationState.Closed)
  54. {
  55. try
  56. {
  57. this.peerNode.InnerNode.Abort();
  58. }
  59. catch (Exception e)
  60. {
  61. if (Fx.IsFatal(e)) throw;
  62. DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
  63. }
  64. }
  65. }
  66. protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
  67. {
  68. // first close the node, then the base
  69. return new ChainedAsyncResult(timeout, callback, state, OnBeginCloseNode, OnEndCloseNode,
  70. base.OnBeginClose, base.OnEndClose);
  71. }
  72. // fisrt step in the chained async close
  73. IAsyncResult OnBeginCloseNode(TimeSpan timeout, AsyncCallback callback, object state)
  74. {
  75. return this.peerNode.InnerNode.BeginClose(timeout, callback, state);
  76. }
  77. protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
  78. {
  79. // open the base, then the node
  80. return new ChainedAsyncResult(timeout, callback, state, base.OnBeginOpen, base.OnEndOpen,
  81. OnBeginOpenNode, OnEndOpenNode);
  82. }
  83. // second step in the chained async open
  84. IAsyncResult OnBeginOpenNode(TimeSpan timeout, AsyncCallback callback, object state)
  85. {
  86. IAsyncResult result = this.peerNode.InnerNode.BeginOpen(timeout, callback, state, true);
  87. return result;
  88. }
  89. protected override void OnClose(TimeSpan timeout)
  90. {
  91. TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
  92. this.peerNode.InnerNode.Close(timeoutHelper.RemainingTime());
  93. base.OnClose(timeoutHelper.RemainingTime());
  94. }
  95. protected override void OnClosing()
  96. {
  97. base.OnClosing();
  98. ReleaseNode();
  99. }
  100. void ReleaseNode()
  101. {
  102. if (!this.released)
  103. {
  104. bool release = false;
  105. lock (ThisLock)
  106. {
  107. if (!this.released)
  108. {
  109. release = this.released = true;
  110. }
  111. }
  112. if (release)
  113. {
  114. this.peerNode.InnerNode.Release();
  115. }
  116. }
  117. }
  118. protected override void OnEndClose(IAsyncResult result)
  119. {
  120. ChainedAsyncResult.End(result);
  121. }
  122. void OnEndCloseNode(IAsyncResult result)
  123. {
  124. PeerNodeImplementation.EndClose(result);
  125. }
  126. protected override void OnEndOpen(IAsyncResult result)
  127. {
  128. ChainedAsyncResult.End(result);
  129. }
  130. void OnEndOpenNode(IAsyncResult result)
  131. {
  132. PeerNodeImplementation.EndOpen(result);
  133. }
  134. protected override void OnEnqueueItem(Message message)
  135. {
  136. // set the message's via to the uri on which it was received
  137. message.Properties.Via = this.via;
  138. if (DiagnosticUtility.ShouldTraceInformation)
  139. {
  140. TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerChannelMessageReceived,
  141. SR.GetString(SR.TraceCodePeerChannelMessageReceived), this, message);
  142. }
  143. }
  144. protected override void OnOpen(TimeSpan timeout)
  145. {
  146. TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
  147. base.OnOpen(timeoutHelper.RemainingTime());
  148. this.peerNode.OnOpen();
  149. this.peerNode.InnerNode.Open(timeoutHelper.RemainingTime(), true);
  150. }
  151. protected override void OnFaulted()
  152. {
  153. base.OnFaulted();
  154. ReleaseNode();
  155. }
  156. }
  157. }