예제 #1
0
func (p *LookupProtocolV1) IOLoop(conn net.Conn) error {
	var err error
	var line string
	var zeroTime time.Time
	to := p.ctx.nsqlookupd.opts.NsqdPingTimeout

	client := NewClientV1(conn)
	reader := bufio.NewReader(client)
	for {
		if to > 0 {
			client.SetReadDeadline(time.Now().Add(to))
		} else {
			client.SetReadDeadline(zeroTime)
		}
		line, err = reader.ReadString('\n')
		if err != nil {
			break
		}

		line = strings.TrimSpace(line)
		params := strings.Split(line, " ")

		var response []byte
		response, err = p.Exec(client, reader, params)
		if err != nil {
			ctx := ""
			if parentErr := err.(protocol.ChildErr).Parent(); parentErr != nil {
				ctx = " - " + parentErr.Error()
			}
			nsqlookupLog.LogErrorf(" [%s] - %s%s", client, err, ctx)

			_, sendErr := protocol.SendResponse(client, []byte(err.Error()))
			if sendErr != nil {
				nsqlookupLog.LogErrorf(" [%s] - %s%s", client, sendErr, ctx)
				break
			}

			// errors of type FatalClientErr should forceably close the connection
			if _, ok := err.(*protocol.FatalClientErr); ok {
				break
			}
			continue
		}

		if response != nil {
			_, err = protocol.SendResponse(client, response)
			if err != nil {
				break
			}
		}
	}

	nsqlookupLog.Logf("CLIENT(%s): closing, %v", client, err)
	if client.peerInfo != nil {
		p.ctx.nsqlookupd.DB.RemoveAllByPeerId(client.peerInfo.Id)
	}
	conn.Close()
	return err
}
예제 #2
0
파일: tcp.go 프로젝트: absolute8511/nsq
func (p *tcpServer) Handle(clientConn net.Conn) {
	nsqlookupLog.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)
	clientConn.SetReadDeadline(time.Now().Add(time.Second * 3))
	_, err := io.ReadFull(clientConn, buf)
	if err != nil {
		nsqlookupLog.Logf(" failed to read protocol version - %s from client: %v", err, clientConn.RemoteAddr())
		clientConn.Close()
		return
	}
	protocolMagic := string(buf)

	nsqlookupLog.Logf("CLIENT(%s): desired protocol magic '%s'",
		clientConn.RemoteAddr(), protocolMagic)

	var prot protocol.Protocol
	switch protocolMagic {
	case "  V1":
		prot = &LookupProtocolV1{ctx: p.ctx}
	default:
		protocol.SendResponse(clientConn, []byte("E_BAD_PROTOCOL"))
		clientConn.Close()
		nsqlookupLog.LogErrorf(" client(%s) bad protocol magic '%s'",
			clientConn.RemoteAddr(), protocolMagic)
		return
	}

	err = prot.IOLoop(clientConn)
	if err != nil {
		if err == io.EOF {
			nsqlookupLog.Logf(" client(%s) - %s", clientConn.RemoteAddr(), err)
		} else {
			nsqlookupLog.LogWarningf(" client(%s) - %s", clientConn.RemoteAddr(), err)
		}
		return
	}
}