/// <summary> /// Build an ISoapInputChannel for the specified endpoint. /// </summary> /// <param name="endpoint"></param> /// <param name="capabilities"></param> /// <returns></returns> ISoapInputChannel ISoapTransport.GetInputChannel( EndpointReference endpoint, SoapChannelCapabilities capabilities ) { if ( endpoint == null ) throw new ArgumentNullException( "endpoint" ); if ( capabilities == SoapChannelCapabilities.ActivelyListening && endpoint.TransportAddress.Scheme != UriScheme ) throw new ArgumentException( "Invalid Transport Scheme specified" ); if ( capabilities != SoapChannelCapabilities.None && capabilities != SoapChannelCapabilities.ActivelyListening ) throw new NotSupportedException( "Unsupported SoapChannelCapabilities Flags" ); Debug( "GetInputChannel TransportAddress: " + endpoint.TransportAddress.ToString( ) ); // // NOTE: Transport level receiving requires that we map the transport address to // one of the local interfaces for the machine. // IPEndPoint localEP = GetLocalIPEndPoint( endpoint.TransportAddress ); if ( localEP == null ) throw new ArgumentException( "Transport address " + endpoint.TransportAddress.ToString( ) + " could not be mapped to a local network interface." ); // // Lock the InputChannels collection while we register the new channel. // lock ( InputChannels.SyncRoot ) { // // Determine whether the request channel already exists. // SoapUdpInputChannel channel = InputChannels[ endpoint ] as SoapUdpInputChannel; SoapUdpSocket socket; if ( channel != null ) return channel; // // Lock the sockets collection while checking for an existing socket // or creating a new one. // lock ( _sockets ) { socket = _sockets[ localEP ] as SoapUdpSocket; if ( socket == null ) { // // There is no suitable socket available. Create a new one, // increment it's reference count and start receiving packets. // socket = new SoapUdpSocket( localEP, _options ); _sockets[ localEP ] = socket; socket.AddReference( ); socket.BeginReceiveFrom( new AsyncCallback( OnReceiveComplete ), socket ); } else { // // Increment the reference count on the listener for unregister behaviour // socket.AddReference( ); } } // // Create the channel, then modify the via so that it matches // the local endpoint address. // // TODO: Fix the race condition here where a packet might be // received before the channel is established for // dispatching. // channel = new SoapUdpInputChannel( endpoint, socket, this ); // // TODO: Do not do Via for the Any address // channel.LocalEndpoint.Via = new Via( ConvertToUri( localEP ) ); // // Record the channel // InputChannels.Add( channel ); return channel; } }
/// <summary> /// Builds an ISoapOutputChannel for the specified endpoint. /// </summary> /// <param name="endpoint">The target endpoint</param> /// <param name="capabilities">The channel capabilities</param> /// <returns>ISoapOutputChannel</returns> ISoapOutputChannel ISoapTransport.GetOutputChannel( EndpointReference endpoint, SoapChannelCapabilities capabilities ) { Debug( "GetOutputChannel TransportAddress: " + endpoint.TransportAddress.ToString( ) ); if ( endpoint.TransportAddress.Scheme != UriScheme ) throw new ArgumentException( "The transport scheme for the specified endpoint does not match this transport.", "endpoint" ); if ( capabilities != SoapChannelCapabilities.None ) throw new NotSupportedException( "Unsupported SoapChannelCapabilities flags. Use SoapChannelCapabilities.None." ); return new SoapUdpOutputChannel( endpoint, new SoapUdpSocket( _options ), this ); }
public ISoapOutputChannel GetOutputChannel( EndpointReference endpoint, SoapChannelCapabilities capabilities ) { //TODO: Endpoint should really be validated. ISoapOutputChannel channel = null; string epDesc = endpoint.TransportAddress.ToString( ); lock ( _outputChannelLock ) { channel = OutputChannels[ epDesc ] as ISoapOutputChannel; if ( channel == null ) { channel = new SoapSqlOutputChannel( endpoint, _options.ConnectionString ); OutputChannels[ epDesc ] = channel; } } return channel; }