func (ch *Channel) Connect(ctx context.Context, hostPort string) (*Connection, error) {
	switch state := ch.State(); state {
	case ChannelClient, ChannelListening:
		break
	default:
		ch.log.Debugf("Connect rejecting new connection as state is %v", state)
		return nil, errInvalidStateForOp
	}

	// The context timeout applies to the whole call, but users may want a lower
	// connect timeout (e.g. for streams).
	if params := getTChannelParams(ctx); params != nil && params.connectTimeout > 0 {
		var cancel context.CancelFunc
		ctx, cancel = context.WithTimeout(ctx, params.connectTimeout)
		defer cancel()
	}

	events := connectionEvents{
		OnActive:           ch.outboundConnectionActive,
		OnCloseStateChange: ch.connectionCloseStateChange,
		OnExchangeUpdated:  ch.exchangeUpdated,
	}

	if err := ctx.Err(); err != nil {
		return nil, GetContextError(err)
	}

	timeout := getTimeout(ctx)
	tcpConn, err := dialContext(ctx, hostPort)
	if err != nil {
		if ne, ok := err.(net.Error); ok && ne.Timeout() {
			ch.log.WithFields(
				LogField{"remoteHostPort", hostPort},
				LogField{"timeout", timeout},
			).Info("Outbound net.Dial timed out.")
			err = ErrTimeout
		} else if ctx.Err() == context.Canceled {
			ch.log.WithFields(
				LogField{"remoteHostPort", hostPort},
			).Info("Outbound net.Dial was cancelled.")
			err = GetContextError(ErrRequestCancelled)
		} else {
			ch.log.WithFields(
				ErrField(err),
				LogField{"remoteHostPort", hostPort},
			).Info("Outbound net.Dial failed.")
		}
		return nil, err
	}

	conn, err := ch.outboundHandshake(ctx, tcpConn, hostPort, events)
	if conn != nil {
		// It's possible that the connection we just created responds with a host:port
		// that is not what we tried to connect to. E.g., we may have connected to
		// 127.0.0.1:1234, but the returned host:port may be 10.0.0.1:1234.
		// In this case, the connection won't be added to 127.0.0.1:1234 peer
		// and so future calls to that peer may end up creating new connections. To
		// avoid this issue, and to avoid clients being aware of any TCP relays, we
		// add the connection to the intended peer.
		if hostPort != conn.remotePeerInfo.HostPort {
			conn.log.Debugf("Outbound connection host:port mismatch, adding to peer %v", conn.remotePeerInfo.HostPort)
			ch.addConnectionToPeer(hostPort, conn, outbound)
		}
	}

	return conn, err
}
func (ch *Channel) Connect(ctx context.Context, hostPort string) (*Connection, error) {
	switch state := ch.State(); state {
	case ChannelClient, ChannelListening:
		break
	default:
		ch.log.Debugf("Connect rejecting new connection as state is %v", state)
		return nil, errInvalidStateForOp
	}

	
	
	if params := getTChannelParams(ctx); params != nil && params.connectTimeout > 0 {
		var cancel context.CancelFunc
		ctx, cancel = context.WithTimeout(ctx, params.connectTimeout)
		defer cancel()
	}

	events := connectionEvents{
		OnActive:           ch.outboundConnectionActive,
		OnCloseStateChange: ch.connectionCloseStateChange,
		OnExchangeUpdated:  ch.exchangeUpdated,
	}

	if err := ctx.Err(); err != nil {
		return nil, GetContextError(err)
	}

	timeout := getTimeout(ctx)
	tcpConn, err := dialContext(ctx, hostPort)
	if err != nil {
		if ne, ok := err.(net.Error); ok && ne.Timeout() {
			ch.log.WithFields(
				LogField{"remoteHostPort", hostPort},
				LogField{"timeout", timeout},
			).Info("Outbound net.Dial timed out.")
			err = ErrTimeout
		} else if ctx.Err() == context.Canceled {
			ch.log.WithFields(
				LogField{"remoteHostPort", hostPort},
			).Info("Outbound net.Dial was cancelled.")
			err = GetContextError(ErrRequestCancelled)
		} else {
			ch.log.WithFields(
				ErrField(err),
				LogField{"remoteHostPort", hostPort},
			).Info("Outbound net.Dial failed.")
		}
		return nil, err
	}

	conn, err := ch.outboundHandshake(ctx, tcpConn, hostPort, events)
	if conn != nil {
		
		
		
		
		
		
		
		if hostPort != conn.remotePeerInfo.HostPort {
			conn.log.Debugf("Outbound connection host:port mismatch, adding to peer %v", conn.remotePeerInfo.HostPort)
			ch.addConnectionToPeer(hostPort, conn, outbound)
		}
	}

	return conn, err
}
func ( ch * Channel ) Connect ( ctx context . Context , hostPort string ) ( * Connection , error ) { switch state := ch . State ( ) ; state { case ChannelClient , ChannelListening : break default : ch . log . Debugf ( " " , state ) return nil , errInvalidStateForOp } // The context timeout applies to the whole call, but users may want a lower // connect timeout (e.g. for streams). if params := getTChannelParams ( ctx ) ; params != nil && params . connectTimeout > 0 { var cancel context . CancelFunc ctx , cancel = context . WithTimeout ( ctx , params . connectTimeout ) defer cancel ( ) } events := connectionEvents { OnActive : ch . outboundConnectionActive , OnCloseStateChange : ch . connectionCloseStateChange , OnExchangeUpdated : ch . exchangeUpdated , } if err := ctx . Err ( ) ; err != nil { return nil , GetContextError ( err ) } timeout := getTimeout ( ctx ) tcpConn , err := dialContext ( ctx , hostPort ) if err != nil { if ne , ok := err . ( net . Error ) ; ok && ne . Timeout ( ) { ch . log . WithFields ( LogField { " " , hostPort } , LogField { " " , timeout } , ) . Info ( " " ) err = ErrTimeout } else if ctx . Err ( ) == context . Canceled { ch . log . WithFields ( LogField { " " , hostPort } , ) . Info ( " " ) err = GetContextError ( ErrRequestCancelled ) } else { ch . log . WithFields ( ErrField ( err ) , LogField { " " , hostPort } , ) . Info ( " " ) } return nil , err } conn , err := ch . outboundHandshake ( ctx , tcpConn , hostPort , events ) if conn != nil { // It's possible that the connection we just created responds with a host:port // that is not what we tried to connect to. E.g., we may have connected to // 127.0.0.1:1234, but the returned host:port may be 10.0.0.1:1234. // In this case, the connection won't be added to 127.0.0.1:1234 peer // and so future calls to that peer may end up creating new connections. To // avoid this issue, and to avoid clients being aware of any TCP relays, we // add the connection to the intended peer. if hostPort != conn . remotePeerInfo . HostPort { conn . log . Debugf ( " " , conn . remotePeerInfo . HostPort ) ch . addConnectionToPeer ( hostPort , conn , outbound ) } } return conn , err }
// Connect creates a new outbound connection to hostPort.
Connect creates a new outbound connection to hostPort .