nsq客戶端go-nsq有段程式碼看不懂

kekemuyu發表於2017-11-05

程式碼來源:go-nsq 中的 conn.go 中的 Connect() Connect() 方法原始碼:

// Connect dials and bootstraps the nsqd connection
// (including IDENTIFY) and returns the IdentifyResponse
func (c *Conn) Connect() (*IdentifyResponse, error) {
    dialer := &net.Dialer{
        LocalAddr: c.config.LocalAddr,
        Timeout:   c.config.DialTimeout,
    }

    conn, err := dialer.Dial("tcp", c.addr)
    if err != nil {
        return nil, err
    }
    c.conn = conn.(*net.TCPConn)
    c.r = conn
    c.w = conn

    _, err = c.Write(MagicV2)
    if err != nil {
        c.Close()
        return nil, fmt.Errorf("[%s] failed to write magic - %s", c.addr, err)
    }

    resp, err := c.identify()
    if err != nil {
        return nil, err
    }

    if resp != nil && resp.AuthRequired {
        if c.config.AuthSecret == "" {
            c.log(LogLevelError, "Auth Required")
            return nil, errors.New("Auth Required")
        }
        err := c.auth(c.config.AuthSecret)
        if err != nil {
            c.log(LogLevelError, "Auth Failed %s", err)
            return nil, err
        }
    }

    c.wg.Add(2)
    atomic.StoreInt32(&c.readLoopRunning, 1)
    go c.readLoop()
    go c.writeLoop()
    return resp, nil
}

這個方法中困惑的地方是 dialer.Dial 返回的 conn 型別是 type Conn interface{..}介面,但是為什麼可以從 conn 中取出 (*net.TCPConn) 型別的資料

conn, err := dialer.Dial("tcp", c.addr)
    if err != nil {
        return nil, err
    }
    c.conn = conn.(*net.TCPConn)
更多原創文章乾貨分享,請關注公眾號
  • nsq客戶端go-nsq有段程式碼看不懂
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章