2 // DuplexSessionChannelBase.cs
5 // Marcos Cobena (marcoscobena@gmail.com)
6 // Atsushi Enomoto <atsushi@ximian.com>
8 // Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
10 // Copyright (C) 2009 Novell, Inc. http://www.novell.com
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.ServiceModel.Channels;
35 namespace System.ServiceModel.Channels
37 internal abstract class DuplexChannelBase : ChannelBase, IDuplexChannel
39 ChannelFactoryBase channel_factory_base;
40 ChannelListenerBase channel_listener_base;
41 EndpointAddress local_address;
42 EndpointAddress remote_address;
45 public DuplexChannelBase (ChannelFactoryBase factory, EndpointAddress remoteAddress, Uri via) : base (factory)
47 channel_factory_base = factory;
48 remote_address = remoteAddress;
53 public DuplexChannelBase (ChannelListenerBase listener) : base (listener)
55 channel_listener_base = listener;
56 local_address = new EndpointAddress (listener.Uri);
60 public virtual EndpointAddress LocalAddress {
61 get { return local_address; }
64 public virtual EndpointAddress RemoteAddress {
65 get { return remote_address; }
69 get { return via ?? RemoteAddress.Uri; }
72 void SetupDelegates ()
74 open_handler = new Action<TimeSpan> (Open);
75 close_handler = new Action<TimeSpan> (Close);
76 send_handler = new AsyncSendHandler (Send);
77 receive_handler = new AsyncReceiveHandler (Receive);
78 wait_handler = new AsyncWaitForMessageHandler (WaitForMessage);
79 try_receive_handler = new TryReceiveHandler (TryReceive);
82 public override T GetProperty<T> ()
84 if (typeof (T) == typeof (IChannelFactory))
85 return (T) (object) channel_factory_base;
86 if (typeof (T) == typeof (IChannelListener))
87 return (T) (object) channel_listener_base;
88 return base.GetProperty<T> ();
92 Action<TimeSpan> open_handler;
94 protected override IAsyncResult OnBeginOpen (TimeSpan timeout, AsyncCallback callback, object state)
96 return open_handler.BeginInvoke (timeout, callback, state);
99 protected override void OnEndOpen (IAsyncResult result)
101 open_handler.EndInvoke (result);
105 Action<TimeSpan> close_handler;
107 protected override IAsyncResult OnBeginClose (TimeSpan timeout, AsyncCallback callback, object state)
109 return close_handler.BeginInvoke (timeout, callback, state);
112 protected override void OnEndClose (IAsyncResult result)
114 close_handler.EndInvoke (result);
119 delegate void AsyncSendHandler (Message message, TimeSpan timeout);
120 AsyncSendHandler send_handler;
122 public virtual IAsyncResult BeginSend (Message message, AsyncCallback callback, object state)
124 return BeginSend (message, DefaultSendTimeout, callback, state);
127 public virtual IAsyncResult BeginSend (Message message, TimeSpan timeout, AsyncCallback callback, object state)
129 return send_handler.BeginInvoke (message, timeout, callback, state);
132 public virtual void EndSend (IAsyncResult result)
134 send_handler.EndInvoke (result);
137 public virtual void Send (Message message)
139 Send (message, this.DefaultSendTimeout);
142 public abstract void Send (Message message, TimeSpan timeout);
146 delegate Message AsyncReceiveHandler (TimeSpan timeout);
147 AsyncReceiveHandler receive_handler;
149 public virtual IAsyncResult BeginReceive (AsyncCallback callback, object state)
151 return BeginReceive (this.DefaultReceiveTimeout, callback, state);
154 public virtual IAsyncResult BeginReceive (TimeSpan timeout, AsyncCallback callback, object state)
156 return receive_handler.BeginInvoke (timeout, callback, state);
159 public virtual Message EndReceive (IAsyncResult result)
161 return receive_handler.EndInvoke (result);
164 public virtual Message Receive ()
166 return Receive (this.DefaultReceiveTimeout);
169 public abstract Message Receive (TimeSpan timeout);
173 delegate bool TryReceiveHandler (TimeSpan timeout, out Message msg);
174 TryReceiveHandler try_receive_handler;
176 public virtual IAsyncResult BeginTryReceive (TimeSpan timeout, AsyncCallback callback, object state)
179 return try_receive_handler.BeginInvoke (timeout, out dummy, callback, state);
182 public virtual bool EndTryReceive (IAsyncResult result, out Message message)
184 return try_receive_handler.EndInvoke (out message, result);
187 public virtual bool TryReceive (TimeSpan timeout, out Message message)
190 message = Receive (timeout);
192 } catch (TimeoutException) {
200 delegate bool AsyncWaitForMessageHandler (TimeSpan timeout);
201 AsyncWaitForMessageHandler wait_handler;
203 public virtual IAsyncResult BeginWaitForMessage (TimeSpan timeout, AsyncCallback callback, object state)
205 return wait_handler.BeginInvoke (timeout, callback, state);
208 public virtual bool EndWaitForMessage (IAsyncResult result)
210 return wait_handler.EndInvoke (result);
213 public abstract bool WaitForMessage (TimeSpan timeout);