MsmqOutputChannel.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. //
  2. // MsmqOutputChannel.cs
  3. //
  4. // Author: Atsushi Enomoto ([email protected])
  5. //
  6. // Copyright (C) 2007 Novell, Inc (http://www.novell.com)
  7. //
  8. // Permission is hereby granted, free of charge, to any person obtaining
  9. // a copy of this software and associated documentation files (the
  10. // "Software"), to deal in the Software without restriction, including
  11. // without limitation the rights to use, copy, modify, merge, publish,
  12. // distribute, sublicense, and/or sell copies of the Software, and to
  13. // permit persons to whom the Software is furnished to do so, subject to
  14. // the following conditions:
  15. //
  16. // The above copyright notice and this permission notice shall be
  17. // included in all copies or substantial portions of the Software.
  18. //
  19. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  20. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  22. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  23. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  24. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  25. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26. //
  27. using System;
  28. using System.IO;
  29. using System.Messaging;
  30. using System.ServiceModel;
  31. using System.Threading;
  32. namespace System.ServiceModel.Channels
  33. {
  34. internal class MsmqOutputChannel : OutputChannelBase
  35. {
  36. MsmqChannelFactory<IOutputChannel> source;
  37. EndpointAddress address;
  38. Uri via;
  39. MessageQueue queue;
  40. public MsmqOutputChannel (MsmqChannelFactory<IOutputChannel> factory,
  41. EndpointAddress address, Uri via)
  42. : base (factory)
  43. {
  44. this.source = factory;
  45. this.address = address;
  46. this.via = via;
  47. }
  48. // IOutputChannel
  49. public override EndpointAddress RemoteAddress {
  50. get { return address; }
  51. }
  52. public override Uri Via {
  53. get { return via; }
  54. }
  55. // Send
  56. public override IAsyncResult BeginSend (Message message, TimeSpan timeout, AsyncCallback callback, object state)
  57. {
  58. ThrowIfDisposedOrNotOpen ();
  59. return new MsmqChannelOutputAsyncResult (this, message, timeout, callback, state);
  60. }
  61. public override void EndSend (IAsyncResult result)
  62. {
  63. if (result == null)
  64. throw new ArgumentNullException ("result");
  65. MsmqChannelOutputAsyncResult r = result as MsmqChannelOutputAsyncResult;
  66. if (r == null)
  67. throw new InvalidOperationException ("Wrong IAsyncResult");
  68. r.WaitEnd ();
  69. }
  70. public override void Send (Message message, TimeSpan timeout)
  71. {
  72. ThrowIfDisposedOrNotOpen ();
  73. MemoryStream ms = new MemoryStream ();
  74. source.MessageEncoder.WriteMessage (message, ms);
  75. queue.Send (ms);
  76. //throw new NotImplementedException ();
  77. }
  78. // Abort
  79. protected override void OnAbort ()
  80. {
  81. throw new NotImplementedException ();
  82. }
  83. // Close
  84. protected override void OnClose (TimeSpan timeout)
  85. {
  86. if (queue != null)
  87. queue.Close ();
  88. queue = null;
  89. }
  90. protected override IAsyncResult OnBeginClose (TimeSpan timeout, AsyncCallback callback, object state)
  91. {
  92. throw new NotImplementedException ();
  93. }
  94. protected override void OnEndClose (IAsyncResult result)
  95. {
  96. throw new NotImplementedException ();
  97. }
  98. // Open
  99. protected override void OnOpen (TimeSpan timeout)
  100. {
  101. // FIXME: is distination really like this?
  102. Uri destination = Via != null ? Via : RemoteAddress.Uri;
  103. queue = new MessageQueue (destination.GetLeftPart (UriPartial.Scheme));
  104. // FIXME: setup queue
  105. }
  106. protected override IAsyncResult OnBeginOpen (TimeSpan timeout, AsyncCallback callback, object state)
  107. {
  108. throw new NotImplementedException ();
  109. }
  110. protected override void OnEndOpen (IAsyncResult result)
  111. {
  112. throw new NotImplementedException ();
  113. }
  114. class MsmqChannelOutputAsyncResult : IAsyncResult
  115. {
  116. MsmqOutputChannel channel;
  117. Message message;
  118. TimeSpan timeout;
  119. AsyncCallback callback;
  120. object state;
  121. AutoResetEvent wait;
  122. bool done, waiting;
  123. Exception error;
  124. public MsmqChannelOutputAsyncResult (MsmqOutputChannel channel, Message message, TimeSpan timeout, AsyncCallback callback, object state)
  125. {
  126. this.channel = channel;
  127. this.message = message;
  128. this.timeout = timeout;
  129. this.callback = callback;
  130. this.state = state;
  131. wait = new AutoResetEvent (false);
  132. Thread t = new Thread (delegate () {
  133. try {
  134. channel.Send (message, timeout);
  135. if (callback != null)
  136. callback (this);
  137. } catch (Exception ex) {
  138. error = ex;
  139. } finally {
  140. done = true;
  141. wait.Set ();
  142. }
  143. });
  144. t.Start ();
  145. }
  146. public WaitHandle AsyncWaitHandle {
  147. get { return wait; }
  148. }
  149. public object AsyncState {
  150. get { return state; }
  151. }
  152. public bool CompletedSynchronously {
  153. get { return done && !waiting; }
  154. }
  155. public bool IsCompleted {
  156. get { return done; }
  157. }
  158. public void WaitEnd ()
  159. {
  160. if (!done) {
  161. waiting = true;
  162. wait.WaitOne (timeout, true);
  163. }
  164. if (error != null)
  165. throw error;
  166. }
  167. }
  168. }
  169. }