示例#1
0
        /// <summary>
        /// Transfers the channel to a waiting connection.
        /// </summary>
        /// <returns>TRUE if the channel should be kept open; FALSE otherwise.</returns>
        public bool TransferListenerChannel(
            uint channelId,
            string serverUri,
            Uri endpointUrl)
        {
            bool accepted = false;
            TcpListenerChannel channel = null;

            lock (m_lock)
            {
                if (!m_channels.TryGetValue(channelId, out channel))
                {
                    throw ServiceResultException.Create(StatusCodes.BadTcpSecureChannelUnknown, "Could not find secure channel request.");
                }
            }

            // notify the application.
            if (ConnectionWaiting != null)
            {
                var args = new TcpConnectionWaitingEventArgs(serverUri, endpointUrl, channel.Socket);
                ConnectionWaiting(this, args);
                accepted = args.Accepted;
            }

            if (accepted)
            {
                lock (m_lock)
                {
                    // remove it so it does not get cleaned up as an inactive connection.
                    m_channels.Remove(channelId);
                }
            }

            return(accepted);
        }
 /// <summary>
 /// Handles requests arriving from a channel.
 /// </summary>
 private void OnRequestReceived(TcpListenerChannel channel, uint requestId, IServiceRequest request)
 {
     try
     {
         if (m_callback != null)
         {
             IAsyncResult result = m_callback.BeginProcessRequest(
                 channel.GlobalChannelId,
                 channel.EndpointDescription,
                 request,
                 OnProcessRequestComplete,
                 new object[] { channel, requestId, request });
         }
     }
     catch (Exception e)
     {
         Utils.Trace(e, "TCPLISTENER - Unexpected error processing request.");
     }
 }
        /// <summary>
        /// Binds a new socket to an existing channel.
        /// </summary>
        public bool ReconnectToExistingChannel(
            IMessageSocket socket,
            uint requestId,
            uint sequenceNumber,
            uint channelId,
            X509Certificate2 clientCertificate,
            ChannelToken token,
            OpenSecureChannelRequest request)
        {
            TcpListenerChannel channel = null;

            lock (m_lock)
            {
                if (!m_channels.TryGetValue(channelId, out channel))
                {
                    throw ServiceResultException.Create(StatusCodes.BadTcpSecureChannelUnknown, "Could not find secure channel referenced in the OpenSecureChannel request.");
                }
            }

            channel.Reconnect(socket, requestId, sequenceNumber, clientCertificate, token, request);

            Utils.Trace("Channel {0} reconnected", channelId);
            return(true);
        }
        /// <summary>
        /// Handles a new connection.
        /// </summary>
        private void OnAccept(object sender, SocketAsyncEventArgs e)
        {
            TcpListenerChannel channel = null;
            bool repeatAccept          = false;

            do
            {
                repeatAccept = false;
                lock (m_lock)
                {
                    Socket listeningSocket = e.UserToken as Socket;

                    if (listeningSocket == null)
                    {
                        Utils.Trace("OnAccept: Listensocket was null.");
                        e.Dispose();
                        return;
                    }

                    // check if the accept socket has been created.
                    if (e.AcceptSocket != null && e.SocketError == SocketError.Success)
                    {
                        try
                        {
                            if (m_reverseConnectListener)
                            {
                                // create the channel to manage incoming reverse connections.
                                channel = new TcpReverseConnectChannel(
                                    m_listenerId,
                                    this,
                                    m_bufferManager,
                                    m_quotas,
                                    m_descriptions);
                            }
                            else
                            {
                                // create the channel to manage incoming connections.
                                channel = new TcpServerChannel(
                                    m_listenerId,
                                    this,
                                    m_bufferManager,
                                    m_quotas,
                                    m_serverCertificate,
                                    m_serverCertificateChain,
                                    m_descriptions);
                            }

                            if (m_callback != null)
                            {
                                channel.SetRequestReceivedCallback(new TcpChannelRequestEventHandler(OnRequestReceived));
                            }

                            // get channel id
                            uint channelId = GetNextChannelId();

                            // start accepting messages on the channel.
                            channel.Attach(channelId, e.AcceptSocket);

                            // save the channel for shutdown and reconnects.
                            m_channels.Add(channelId, channel);
                        }
                        catch (Exception ex)
                        {
                            Utils.Trace(ex, "Unexpected error accepting a new connection.");
                        }
                    }

                    e.Dispose();

                    if (e.SocketError != SocketError.OperationAborted)
                    {
                        // go back and wait for the next connection.
                        try
                        {
                            e            = new SocketAsyncEventArgs();
                            e.Completed += OnAccept;
                            e.UserToken  = listeningSocket;
                            if (!listeningSocket.AcceptAsync(e))
                            {
                                repeatAccept = true;
                            }
                        }
                        catch (Exception ex)
                        {
                            Utils.Trace(ex, "Unexpected error listening for a new connection.");
                        }
                    }
                }
            } while (repeatAccept);
        }