func (p *LookupProtocolV1) IOLoop(conn net.Conn) error { var err error var line string client := NewClientV1(conn) err = nil reader := bufio.NewReader(client) for { line, err = reader.ReadString('\n') if err != nil { break } line = strings.TrimSpace(line) params := strings.Split(line, " ") response, err := p.Exec(client, reader, params) if err != nil { context := "" if parentErr := err.(util.ChildErr).Parent(); parentErr != nil { context = " - " + parentErr.Error() } log.Printf("ERROR: [%s] - %s%s", client, err.Error(), context) _, err = util.SendResponse(client, []byte(err.Error())) if err != nil { break } // errors of type FatalClientErr should forceably close the connection if _, ok := err.(*util.FatalClientErr); ok { break } continue } if response != nil { _, err = util.SendResponse(client, response) if err != nil { break } } } log.Printf("CLIENT(%s): closing", client) if client.peerInfo != nil { registrations := p.context.nsqlookupd.DB.LookupRegistrations(client.peerInfo.id) for _, r := range registrations { if removed, _ := p.context.nsqlookupd.DB.RemoveProducer(r, client.peerInfo.id); removed { log.Printf("DB: client(%s) UNREGISTER category:%s key:%s subkey:%s", client, r.Category, r.Key, r.SubKey) } } } return err }
func (p *tcpServer) Handle(clientConn net.Conn) { log.Printf("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) _, err := io.ReadFull(clientConn, buf) if err != nil { log.Printf("ERROR: failed to read protocol version - %s", err.Error()) return } protocolMagic := string(buf) log.Printf("CLIENT(%s): desired protocol magic '%s'", clientConn.RemoteAddr(), protocolMagic) var prot util.Protocol switch protocolMagic { case " V1": prot = &LookupProtocolV1{context: p.context} default: util.SendResponse(clientConn, []byte("E_BAD_PROTOCOL")) clientConn.Close() log.Printf("ERROR: client(%s) bad protocol magic '%s'", clientConn.RemoteAddr(), protocolMagic) return } err = prot.IOLoop(clientConn) if err != nil { log.Printf("ERROR: client(%s) - %s", clientConn.RemoteAddr(), err.Error()) return } }