1 // 2 // DuplexSessionChannelBase.cs 3 // 4 // Author: 5 // Marcos Cobena (marcoscobena@gmail.com) 6 // Atsushi Enomoto <atsushi@ximian.com> 7 // 8 // Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/) 9 // 10 // Copyright (C) 2009 Novell, Inc. http://www.novell.com 11 // 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: 19 // 20 // The above copyright notice and this permission notice shall be 21 // included in all copies or substantial portions of the Software. 22 // 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. 30 // 31 32 using System; 33 using System.ServiceModel.Channels; 34 35 namespace System.ServiceModel.Channels 36 { 37 internal abstract class DuplexChannelBase : ChannelBase, IDuplexChannel 38 { 39 ChannelFactoryBase channel_factory_base; 40 ChannelListenerBase channel_listener_base; 41 EndpointAddress local_address; 42 EndpointAddress remote_address; 43 Uri via; 44 DuplexChannelBase(ChannelFactoryBase factory, EndpointAddress remoteAddress, Uri via)45 public DuplexChannelBase (ChannelFactoryBase factory, EndpointAddress remoteAddress, Uri via) : base (factory) 46 { 47 channel_factory_base = factory; 48 remote_address = remoteAddress; 49 this.via = via; 50 SetupDelegates (); 51 } 52 DuplexChannelBase(ChannelListenerBase listener)53 public DuplexChannelBase (ChannelListenerBase listener) : base (listener) 54 { 55 channel_listener_base = listener; 56 local_address = new EndpointAddress (listener.Uri); 57 SetupDelegates (); 58 } 59 60 public virtual EndpointAddress LocalAddress { 61 get { return local_address; } 62 } 63 64 public virtual EndpointAddress RemoteAddress { 65 get { return remote_address; } 66 } 67 68 public Uri Via { 69 get { return via ?? RemoteAddress.Uri; } 70 } 71 SetupDelegates()72 void SetupDelegates () 73 { 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); 80 } 81 GetProperty()82 public override T GetProperty<T> () 83 { 84 if (typeof (T) == typeof (MessageVersion)) { 85 if (channel_factory_base is IHasMessageEncoder) 86 return (T) (object) ((IHasMessageEncoder) channel_factory_base).MessageEncoder.MessageVersion; 87 if (channel_listener_base is IHasMessageEncoder) 88 return (T) (object) ((IHasMessageEncoder) channel_listener_base).MessageEncoder.MessageVersion; 89 } 90 if (typeof (T) == typeof (IChannelFactory)) 91 return (T) (object) channel_factory_base; 92 if (typeof (T) == typeof (IChannelListener)) 93 return (T) (object) channel_listener_base; 94 return base.GetProperty<T> (); 95 } 96 97 // Open 98 Action<TimeSpan> open_handler; 99 OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)100 protected override IAsyncResult OnBeginOpen (TimeSpan timeout, AsyncCallback callback, object state) 101 { 102 return open_handler.BeginInvoke (timeout, callback, state); 103 } 104 OnEndOpen(IAsyncResult result)105 protected override void OnEndOpen (IAsyncResult result) 106 { 107 open_handler.EndInvoke (result); 108 } 109 110 // Close 111 Action<TimeSpan> close_handler; 112 OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)113 protected override IAsyncResult OnBeginClose (TimeSpan timeout, AsyncCallback callback, object state) 114 { 115 return close_handler.BeginInvoke (timeout, callback, state); 116 } 117 OnEndClose(IAsyncResult result)118 protected override void OnEndClose (IAsyncResult result) 119 { 120 close_handler.EndInvoke (result); 121 } 122 123 // Send 124 AsyncSendHandler(Message message, TimeSpan timeout)125 delegate void AsyncSendHandler (Message message, TimeSpan timeout); 126 AsyncSendHandler send_handler; 127 BeginSend(Message message, AsyncCallback callback, object state)128 public virtual IAsyncResult BeginSend (Message message, AsyncCallback callback, object state) 129 { 130 return BeginSend (message, DefaultSendTimeout, callback, state); 131 } 132 BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)133 public virtual IAsyncResult BeginSend (Message message, TimeSpan timeout, AsyncCallback callback, object state) 134 { 135 return send_handler.BeginInvoke (message, timeout, callback, state); 136 } 137 EndSend(IAsyncResult result)138 public virtual void EndSend (IAsyncResult result) 139 { 140 send_handler.EndInvoke (result); 141 } 142 Send(Message message)143 public virtual void Send (Message message) 144 { 145 Send (message, this.DefaultSendTimeout); 146 } 147 Send(Message message, TimeSpan timeout)148 public abstract void Send (Message message, TimeSpan timeout); 149 150 // Receive 151 AsyncReceiveHandler(TimeSpan timeout)152 delegate Message AsyncReceiveHandler (TimeSpan timeout); 153 AsyncReceiveHandler receive_handler; 154 BeginReceive(AsyncCallback callback, object state)155 public virtual IAsyncResult BeginReceive (AsyncCallback callback, object state) 156 { 157 return BeginReceive (this.DefaultReceiveTimeout, callback, state); 158 } 159 BeginReceive(TimeSpan timeout, AsyncCallback callback, object state)160 public virtual IAsyncResult BeginReceive (TimeSpan timeout, AsyncCallback callback, object state) 161 { 162 return receive_handler.BeginInvoke (timeout, callback, state); 163 } 164 EndReceive(IAsyncResult result)165 public virtual Message EndReceive (IAsyncResult result) 166 { 167 return receive_handler.EndInvoke (result); 168 } 169 Receive()170 public virtual Message Receive () 171 { 172 return Receive (this.DefaultReceiveTimeout); 173 } 174 Receive(TimeSpan timeout)175 public virtual Message Receive (TimeSpan timeout) 176 { 177 Message msg; 178 if (!TryReceive (timeout, out msg)) 179 throw new TimeoutException (); 180 return msg; 181 } 182 183 // TryReceive 184 TryReceiveHandler(TimeSpan timeout, out Message msg)185 delegate bool TryReceiveHandler (TimeSpan timeout, out Message msg); 186 TryReceiveHandler try_receive_handler; 187 BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)188 public virtual IAsyncResult BeginTryReceive (TimeSpan timeout, AsyncCallback callback, object state) 189 { 190 Message dummy; 191 return try_receive_handler.BeginInvoke (timeout, out dummy, callback, state); 192 } 193 EndTryReceive(IAsyncResult result, out Message message)194 public virtual bool EndTryReceive (IAsyncResult result, out Message message) 195 { 196 return try_receive_handler.EndInvoke (out message, result); 197 } 198 TryReceive(TimeSpan timeout, out Message message)199 public abstract bool TryReceive (TimeSpan timeout, out Message message); 200 201 // WaitForMessage 202 AsyncWaitForMessageHandler(TimeSpan timeout)203 delegate bool AsyncWaitForMessageHandler (TimeSpan timeout); 204 AsyncWaitForMessageHandler wait_handler; 205 BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state)206 public virtual IAsyncResult BeginWaitForMessage (TimeSpan timeout, AsyncCallback callback, object state) 207 { 208 return wait_handler.BeginInvoke (timeout, callback, state); 209 } 210 EndWaitForMessage(IAsyncResult result)211 public virtual bool EndWaitForMessage (IAsyncResult result) 212 { 213 return wait_handler.EndInvoke (result); 214 } 215 WaitForMessage(TimeSpan timeout)216 public abstract bool WaitForMessage (TimeSpan timeout); 217 } 218 } 219