在上一章nsqlookupd
初探中瞭解到,nsqlookupd
中開啓了一個tcpServer
和一個 httpServer
,那麼今天咱們來初步瞭解下tcpServer
。sql
廢話很少說,直接上代碼吧,簡單粗暴點比較好。tcp
type tcpServer struct { ctx *Context //上一章中提到的Contexto } func (p *tcpServer) Handle(clientConn net.Conn) { p.ctx.nsqlookupd.logf("TCP: new client(%s)", clientConn.RemoteAddr()) // The client should initialize itself by sending a 4 byte sequence indicating // the version of the protocol that it intends to communicate, this will allow us // to gracefully upgrade the protocol away from text/line oriented to whatever... //這裏有註釋了,可是我英文很差,因此仍是加上本身的註釋吧,若是有錯誤,歡迎你們指正哦 buf := make([]byte, 4) //初始化4個字節的buf,用來獲取協議中的版本號 _, err := io.ReadFull(clientConn, buf) if err != nil { p.ctx.nsqlookupd.logf("ERROR: failed to read protocol version - %s", err) return } protocolMagic := string(buf) p.ctx.nsqlookupd.logf("CLIENT(%s): desired protocol magic '%s'", clientConn.RemoteAddr(), protocolMagic) var prot protocol.Protocol switch protocolMagic { case " V1": //若是是 V1,注意4個字節哦,前面有兩個空格字符 prot = &LookupProtocolV1{ctx: p.ctx} //初始化一個lookupProtocolV1的指針,將Context 組合進去 具體參考nsq/nsqlookupd/lookup_protocol_v1.go文件裏的代碼 default: //若是不是 V1 則關閉鏈接,返回E_BAD_PROTOCOL protocol.SendResponse(clientConn, []byte("E_BAD_PROTOCOL")) clientConn.Close() p.ctx.nsqlookupd.logf("ERROR: client(%s) bad protocol magic '%s'", clientConn.RemoteAddr(), protocolMagic) return } //到這裏纔是整個tcpServer中的重頭戲,不過今天就講到這裏了。下一章就重點分析下這個IOLoop err = prot.IOLoop(clientConn) if err != nil { p.ctx.nsqlookupd.logf("ERROR: client(%s) - %s", clientConn.RemoteAddr(), err) return } }
經過對上面代碼的分析,大體瞭解了tcpServer
的鏈接處理過程,下一章就重點介紹IOLoop
這個方法,好戲都在這裏。oop