Pergunta

Eu tenho um programa python que usa atualmente um cliente de tcp/ip módulo escrevi para receber dados de um servidor de streaming.O servidor saídas de linhas de dados.

Meu cliente TCP classe é bastante primitivo e eu quero refatorar para usar uma torcida ReconnectingClientFactory.

O principal programa obtém dados a partir de um readLines função no meu Cliente de TCP que 'produz' as linhas como eles são recebidos.

O cliente de TCP método é acessado por:

for msg_buffer in self.myTcpClient.readLines():
    do some stuff with the data in msg_buffer

No meu Cliente de TCP o método readLines em essência parece:

while True:
    newLine = self.sock.recv(self.buffer_size)
    yield newLine

Quando eu implementar a torcida cliente eu vou querer de alguma forma para que se comporte como um iterador e dados de produção.Eu suponho que eu gostaria de fazer algo no protocolo dataReceived método.

Eu estou perdido tentando descobrir como isso funciona.Parece-me que a torcida diferidos são destinados para este tipo de uso, mas eu não consigo descobrir como usar um adiada para o meu propósito (se minha suposição sobre diferido é correto).

Em um mundo perfeito, a torcida do cliente produziria as linhas como receber uma chamada semelhante para o presente método iria fazer o trabalho.i.e.

class GetData(protocol):
    def dataReceived(self, data):
        yield data

Mas eu acho que é uma simplificação excessiva.

Em resumo, o que eu estou tentando fazer é implementar uma torcida reconectar TCP cliente que se comporta algo como o meu método readLines e podem ser acessados com mais ou menos assim:

for msg_buffer in self.twistedTcpClient.readLines():

Qualquer ponteiros vai ser muito apreciada

ATUALIZAÇÃO:Eu só tropeçou em 'Crochê' para a torcida.À primeira vista, Crochê parece ter sido concebido exatamente para o tipo de modelo que eu preciso...Vou relatar de volta depois de alguns testes

Foi útil?

Solução

A Torcida maneira de fazer isso seria escrever um Protocolo.Em vez de fazer:

for line in self.twistedTcpClient.readLines():
    process_line(line) ...

Você gostaria de escrever o seu Protocolo (talvez por uma subclassificação twisted.protocols.basic.LineReceiver):

class MyProtocol(LineReceiver):
    ...
    def lineReceived(self, line):
        process_line(line) ...

Você quer refatorar seu código para usar o lineReceived de retorno de chamada em vez de ter uma iteração do loop.

O que você tem escrito:

for line in self.twistedTcpClient.readLines():
    process_line(line) ...

é problemático, uma vez que Torcida é assíncrona.Não há nenhuma maneira para Torcida para dar a volta a fazer qualquer outra coisa enquanto espera para twistedTcpClient.readLines() o método.

Eu sugiro escrever um protocolo, mas se você realmente insiste em ter este iterador padrão, então você pode ser capaz de fazer isso:

@inlineCallbacks
def my_func():
    while True:
        try:
            line = yield self.twistedTcpClient.getNextLine()
        except StopIteration:
            break

        process_line(line) ...

Agora, o mais complicado é fazer com que twistedTcpClient retorno Deferreds para cada chamada para getNextLine().Talvez algo como isto:

class MyProtocol(LineReceiver):
    ...
    def getNextLine(self):
        self.defer_given_out = Deferred()

    def lineReceived(self, line):
        self.defer_given_out.callback(line)

    def connectionLost(self):
        self.defer_given_out.errback(StopIteration())

(este é apenas um exemplo que ilustra a idéia, o que você teria para estendê-lo a lidar com os detalhes.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top