1 // 2 // Author: Atsushi Enomoto <atsushi@ximian.com> 3 // 4 // Copyright (C) 2009,2010 Novell, Inc (http://www.novell.com) 5 // 6 // Permission is hereby granted, free of charge, to any person obtaining 7 // a copy of this software and associated documentation files (the 8 // "Software"), to deal in the Software without restriction, including 9 // without limitation the rights to use, copy, modify, merge, publish, 10 // distribute, sublicense, and/or sell copies of the Software, and to 11 // permit persons to whom the Software is furnished to do so, subject to 12 // the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be 15 // included in all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 // 25 using System; 26 using System.Collections.Generic; 27 using System.Collections.ObjectModel; 28 using System.Linq; 29 using System.ServiceModel; 30 using System.ServiceModel.Channels; 31 using System.ServiceModel.Description; 32 using System.ServiceModel.Dispatcher; 33 34 namespace System.ServiceModel.Discovery 35 { 36 //* Strange, but this causes compiler error at DiscoveryClientBindingElement. 37 38 internal class DiscoveryChannel<TChannel> : DiscoveryChannelBase, IRequestSessionChannel, IDuplexSessionChannel 39 { 40 DiscoveryChannelFactory<TChannel> factory; 41 TChannel inner; 42 DiscoveryChannel(DiscoveryChannelFactory<TChannel> factory, EndpointAddress address, Uri via)43 public DiscoveryChannel (DiscoveryChannelFactory<TChannel> factory, EndpointAddress address, Uri via) 44 : base (factory) 45 { 46 this.factory = factory; 47 RemoteAddress = address; 48 Via = via; 49 } 50 51 public EndpointAddress RemoteAddress { get; private set; } 52 public Uri Via { get; private set; } 53 public EndpointAddress LocalAddress { 54 get { return ((IDuplexSessionChannel) inner).LocalAddress; } 55 } 56 57 IDuplexSession ISessionChannel<IDuplexSession>.Session { 58 get { return ((IDuplexSessionChannel) inner).Session; } 59 } 60 61 IOutputSession ISessionChannel<IOutputSession>.Session { 62 get { return ((IOutputSessionChannel) inner).Session; } 63 } 64 65 Action<TimeSpan> open_delegate, close_delegate; 66 OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)67 protected override IAsyncResult OnBeginClose (TimeSpan timeout, AsyncCallback callback, object state) 68 { 69 if (close_delegate == null) 70 close_delegate = new Action<TimeSpan> (OnClose); 71 return close_delegate.BeginInvoke (timeout, callback, state); 72 } 73 OnEndClose(IAsyncResult result)74 protected override void OnEndClose (IAsyncResult result) 75 { 76 close_delegate.EndInvoke (result); 77 } 78 OnAbort()79 protected override void OnAbort () 80 { 81 if (inner != null) { 82 ((IChannel) inner).Abort (); 83 inner = default (TChannel); 84 } 85 } 86 OnClose(TimeSpan timeout)87 protected override void OnClose (TimeSpan timeout) 88 { 89 if (inner != null) { 90 ((IChannel) inner).Close (timeout); 91 inner = default (TChannel); 92 } 93 } 94 OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)95 protected override IAsyncResult OnBeginOpen (TimeSpan timeout, AsyncCallback callback, object state) 96 { 97 if (open_delegate == null) 98 open_delegate = new Action<TimeSpan> (OnOpen); 99 return open_delegate.BeginInvoke (timeout, callback, state); 100 } 101 OnEndOpen(IAsyncResult result)102 protected override void OnEndOpen (IAsyncResult result) 103 { 104 open_delegate.EndInvoke (result); 105 } 106 OnOpen(TimeSpan timeout)107 protected override void OnOpen (TimeSpan timeout) 108 { 109 // FIXME: use timeout 110 DateTime start = DateTime.UtcNow; 111 inner = CreateDiscoveryInnerChannel<TChannel> (factory); 112 ((IChannel) inner).Open (timeout - (DateTime.UtcNow - start)); 113 } 114 Request(Message msg)115 public Message Request (Message msg) 116 { 117 return Request (msg, DefaultSendTimeout + DefaultReceiveTimeout); 118 } 119 Request(Message msg, TimeSpan timeout)120 public Message Request (Message msg, TimeSpan timeout) 121 { 122 return ((IRequestChannel) inner).Request (msg, timeout); 123 } 124 BeginRequest(Message msg, AsyncCallback callback, object state)125 public IAsyncResult BeginRequest (Message msg, AsyncCallback callback, object state) 126 { 127 return BeginRequest (msg, DefaultSendTimeout + DefaultReceiveTimeout, callback, state); 128 } 129 BeginRequest(Message msg, TimeSpan timeout, AsyncCallback callback, object state)130 public IAsyncResult BeginRequest (Message msg, TimeSpan timeout, AsyncCallback callback, object state) 131 { 132 return ((IRequestChannel) inner).BeginRequest (msg, timeout, callback, state); 133 } 134 EndRequest(IAsyncResult result)135 public Message EndRequest (IAsyncResult result) 136 { 137 return ((IRequestChannel) inner).EndRequest (result); 138 } 139 Receive()140 public Message Receive () 141 { 142 return Receive (DefaultReceiveTimeout); 143 } 144 Receive(TimeSpan timeout)145 public Message Receive (TimeSpan timeout) 146 { 147 return ((IInputChannel) inner).Receive (timeout); 148 } 149 BeginReceive(AsyncCallback callback, object state)150 public IAsyncResult BeginReceive (AsyncCallback callback, object state) 151 { 152 return BeginReceive (DefaultReceiveTimeout, callback, state); 153 } 154 BeginReceive(TimeSpan timeout, AsyncCallback callback, object state)155 public IAsyncResult BeginReceive (TimeSpan timeout, AsyncCallback callback, object state) 156 { 157 return ((IInputChannel) inner).BeginReceive (timeout, callback, state); 158 } 159 EndReceive(IAsyncResult result)160 public Message EndReceive (IAsyncResult result) 161 { 162 return ((IInputChannel) inner).EndReceive (result); 163 } 164 TryReceive(out Message msg)165 public bool TryReceive (out Message msg) 166 { 167 return TryReceive (DefaultReceiveTimeout, out msg); 168 } 169 TryReceive(TimeSpan timeout, out Message msg)170 public bool TryReceive (TimeSpan timeout, out Message msg) 171 { 172 return ((IInputChannel) inner).TryReceive (timeout, out msg); 173 } 174 BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)175 public IAsyncResult BeginTryReceive (TimeSpan timeout, AsyncCallback callback, object state) 176 { 177 return ((IInputChannel) inner).BeginTryReceive (timeout, callback, state); 178 } 179 EndTryReceive(IAsyncResult result, out Message msg)180 public bool EndTryReceive (IAsyncResult result, out Message msg) 181 { 182 return ((IInputChannel) inner).EndTryReceive (result, out msg); 183 } 184 WaitForMessage(TimeSpan timeout)185 public bool WaitForMessage (TimeSpan timeout) 186 { 187 return ((IInputChannel) inner).WaitForMessage (timeout); 188 } 189 BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state)190 public IAsyncResult BeginWaitForMessage (TimeSpan timeout, AsyncCallback callback, object state) 191 { 192 return ((IInputChannel) inner).BeginWaitForMessage (timeout, callback, state); 193 } 194 EndWaitForMessage(IAsyncResult result)195 public bool EndWaitForMessage (IAsyncResult result) 196 { 197 return ((IInputChannel) inner).EndWaitForMessage (result); 198 } 199 Send(Message msg)200 public void Send (Message msg) 201 { 202 Send (msg, DefaultSendTimeout); 203 } 204 Send(Message msg, TimeSpan timeout)205 public void Send (Message msg, TimeSpan timeout) 206 { 207 ((IOutputChannel) inner).Send (msg, timeout); 208 } 209 BeginSend(Message msg, AsyncCallback callback, object state)210 public IAsyncResult BeginSend (Message msg, AsyncCallback callback, object state) 211 { 212 return BeginSend (msg, DefaultSendTimeout, callback, state); 213 } 214 BeginSend(Message msg, TimeSpan timeout, AsyncCallback callback, object state)215 public IAsyncResult BeginSend (Message msg, TimeSpan timeout, AsyncCallback callback, object state) 216 { 217 return ((IOutputChannel) inner).BeginSend (msg, timeout, callback, state); 218 } 219 EndSend(IAsyncResult result)220 public void EndSend (IAsyncResult result) 221 { 222 ((IOutputChannel) inner).EndSend (result); 223 } 224 } 225 //*/ 226 227 internal class DiscoveryRequestChannel : RequestChannelBase 228 { DiscoveryRequestChannel(DiscoveryChannelFactory<IRequestChannel> factory, EndpointAddress address, Uri via)229 public DiscoveryRequestChannel (DiscoveryChannelFactory<IRequestChannel> factory, EndpointAddress address, Uri via) 230 : base (factory, address, via) 231 { 232 this.factory = factory; 233 } 234 235 DiscoveryChannelFactory<IRequestChannel> factory; 236 IRequestChannel inner; 237 DiscoveryClient client; 238 OnOpen(TimeSpan timeout)239 protected override void OnOpen (TimeSpan timeout) 240 { 241 inner = CreateDiscoveryInnerChannel<IRequestChannel> (factory); 242 } 243 OnClose(TimeSpan timeout)244 protected override void OnClose (TimeSpan timeout) 245 { 246 if (inner != null) { 247 inner.Close (timeout); 248 inner = null; 249 } 250 } 251 OnAbort()252 protected override void OnAbort () 253 { 254 if (inner != null) { 255 inner.Abort (); 256 inner = null; 257 } 258 } 259 Request(Message input, TimeSpan timeout)260 public override Message Request (Message input, TimeSpan timeout) 261 { 262 ThrowIfDisposedOrNotOpen (); 263 return inner.Request (input, timeout); 264 } 265 } 266 } 267