示例#1
0
        private void _connect(Dictionary <string, string> data = null)
        {
            for (int i = 0; i < _ipAddresses.Count; i++)
            {
                try
                {
                    // if the IP address is not supported then skip, e.g. IPv6 address but not supported by network card
                    if (_ipAddresses[i] == null ||
                        (_ipAddresses[i].AddressFamily == AddressFamily.InterNetwork && !Socket.OSSupportsIPv4) ||
                        (_ipAddresses[i].AddressFamily == AddressFamily.InterNetworkV6 && !Socket.OSSupportsIPv6))
                    {
                        continue;
                    }

                    // attempt to connect to remote endpoint (will throw if not available)
                    _tcpClient     = ComponentFactory.BuildTcpClient(_ipAddresses[i].ToString(), _port, _sslSettings);
                    _networkStream = _tcpClient.GetStream();
                    _networkStream.AuthenticateAsClient();

                    Log.InfoFormat("[{0}] Connected to {1}:{2}", ID, _ipAddresses[i], _port);

                    break;
                }
                catch (Exception e)
                {
                    Log.ErrorFormat($"Unable to connect to remote endpoint: {e.Message}");

                    _tcpClient     = null;
                    _networkStream = null;
                }
            }

            // did one of the addresses make a connection
            if (_tcpClient != null && _networkStream != null)
            {
                // create and start the frame decoder
                _streamDecoderTask = _decodeStreamAsync(_networkStream, _cts.Token);

                // update state and send start frame
                State = ConnectionState.ConnectionStartSent;
                _sendFrame(FrameType.ConnectionStart, Frame.CreateConnectionStartFrame(data));

                // block until the connection is established, errors, or times out
                var index = WaitHandle.WaitAny(new[] { _connectionOpen, _connectionError }, 2000);

                // what was the result?
                switch (index)
                {
                // success - return the established connection
                case 0: return;

                // the connection failed
                case 1: throw new ConnectionException("Unable to establish connection");

                // establishing the connection timed out
                case WaitHandle.WaitTimeout: throw new ConnectionTimeoutException("Establishing a conneciton the remote endpoint timed out");

                // should never each this point
                default: throw new Exception();
                }
            }
            else
            {
                // failed to connect to the remote endpoint
                throw new ConnectionException("Unable to establish connection");
            }
        }