/// <summary> /// Constructor. /// </summary> /// <param name="endpoint">The local endpoint for the channel.</param> /// <param name="socket">The socket for the channel.</param> /// <param name="transport">The transport for the channel.</param> internal SoapUdpInputChannel( EndpointReference endpoint, SoapUdpSocket socket, SoapUdpTransport transport ) : base(endpoint) { Debug.Assert( socket != null ); Debug.Assert( transport != null ); _remoteEndpoint = null; _socket = socket; _transport = transport; }
/// <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; } }