Рефакторинг для скрученного клиента TCP из существующего блокирующего кода
-
20-12-2019 - |
Вопрос
У меня есть программа Python, которая в настоящее время использует клиентский модуль TCP / IP, который я написал для получения данных с потокового сервера. Сервер выводит строки данных.
Мой класс клиента TCP довольно примитив, и я хочу ревертировать, чтобы использовать скрученные рекордуктыClientFactory.
Основная программа в настоящее время получает данные из функции readleines в моем клиенте TCP, что «дает» линии, как они получены.
Клиентский метод TCP обращается к:
for msg_buffer in self.myTcpClient.readLines():
do some stuff with the data in msg_buffer
.
В моем клиенте TCP Метод Readleines по сути выглядит:
while True:
newLine = self.sock.recv(self.buffer_size)
yield newLine
.
Когда я реализую вируемый клиент, я хочу, чтобы по-своему вести себя как итератор и данные данные. Я предполагаю, что я сделаю что-то в методе DataReceied протокола.
Я потерян, пытаясь выяснить, как это работает. Мне кажется, что скрученные отложенные предназначены для такого использования, но я не могу выяснить, как использовать отсрочку для моей цели (если мое предположение о отложенном правильном).
В идеальном мире витой клиент даст линии, полученные, поэтому вызов, аналогичный настоящим методу, будет выполнять работу. I.e.
class GetData(protocol):
def dataReceived(self, data):
yield data
.
Но я думаю, что это упрощение.
Таким образом, то, что я пытаюсь сделать, это реализовать скрученный переподключенный клиент TCP, который ведет себя что-то вроде метода My Readleines и может быть доступ к более или менее:
for msg_buffer in self.twistedTcpClient.readLines():
.
Любые указатели будут высоко оценены
Обновление: Я просто наткнулся на «крючком» для скрученного. На первый взгляд вязание крючком, кажется, было разработано для именно такой модели, которую мне нужна ... Я отчинусь назад после некоторого тестирования
Решение
Вибрированный способ сделать это было бы написать протокол.Вместо того, чтобы делать:
for line in self.twistedTcpClient.readLines():
process_line(line) ...
.
Вы бы написали свой протокол (может быть, подклассный генеракодицетагкод):
class MyProtocol(LineReceiver):
...
def lineReceived(self, line):
process_line(line) ...
.
Вы хотите решить ваш код, чтобы использовать обратный вызов twisted.protocols.basic.LineReceiver
, а не имел итерационный цикл.
Что вы написали:
for line in self.twistedTcpClient.readLines():
process_line(line) ...
.
проблематично, как скрученный асинхронный.Для того, чтобы скрутить, чтобы обойти, чтобы сделать что-нибудь еще, в ожидании метода lineReceived
.
Я предлагаю написать протокол, но если вы действительно настаиваете на том, чтобы иметь этот шаблон итератора, вы можете сделать это:
@inlineCallbacks
def my_func():
while True:
try:
line = yield self.twistedTcpClient.getNextLine()
except StopIteration:
break
process_line(line) ...
.
Теперь сложная вещь - сделать twistedTcpClient.readLines()
ReplacodicCode для каждого вызова для GetNextline ().Может быть, что-то вроде этого:
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())
.
(это просто пример, который иллюстрирует идею, вам нужно будет продлить ее для обработки деталей.)