리팩터링을 위한 꼬이 tcp 클라이언트에서 기존의 코드 차단
-
20-12-2019 - |
문제
나는 파이썬 프로그램에서 현재 사용하는 tcp/ip 클라이언트 모듈을 썼을 받에서 데이터 스트리밍 서버입니다.서버 출력 라인의 데이터입니다.
내 TCP 클라이언트 클래스를 상당히 원시적이고 내가 원하는 형식을 사용하 꼬 ReconnectingClientFactory.
주요 프로그램은 현재에서 데이터를 가져 readLines 기능에 내 TCP 클라이언트는'수익률'는 라인으로 그들이 받았습니다.
TCP 클라이언트 방법에 액세스:
for msg_buffer in self.myTcpClient.readLines():
do some stuff with the data in msg_buffer
내 TCP 클라이언트에 readLines 방법이 본질적으로 같:
while True:
newLine = self.sock.recv(self.buffer_size)
yield newLine
을 때 나를 구현하는 꼬 클라이언트를 원하는 방법에 대한 그것을 행동으로 반복기 및 수확량 데이터입니다.나는 가정이 나는 뭔가에서 프로토콜 dataReceived 방법입니다.
길을 잃었어요하고 어떻게 작동합니다.그것은 나에게 나타나는 꼬 지연은 이런 종류의 사용 그러나 나는 방법을 알아낼 수 없습니다 사용하는 지연에 대한 나의 목적(는 경우 나의 가정에 대한 연기는 올바른).
완벽한 세계에서 트위스트 클라이언트로 산출 라인으로 받은 그래서 전화와 비슷한 현재의 방법은 작업을 수행합니다.즉
class GetData(protocol):
def dataReceived(self, data):
yield data
하지만 제 생각에 그 사실을 축소시켜서 말한 것입니다.
요약에서 무엇을 하려고 해요 하 구현 꼬이는 다시 연결 TCP 동작하는 클라이언트가 같은 내 readLines 방법에 액세스할 수 있습니다 더 많거나 적은 다음과 같:
for msg_buffer in self.twistedTcpClient.readLines():
어떤 점이 많이 주시면 감사하겠습니다
업데이트:나는 그냥 우연히 발견'질에 대한'꼬여 있습니다.첫눈에 뜨개질을 가지고 나타나도록 설계되었 정확히 종류의 모델 나가 필요로 하는...내가 다시 보고한 후에는 몇 가지 테스트
해결책
트위스트 방법을 이렇게 하는 것을 작성 프로토콜입니다.대신:
for line in self.twistedTcpClient.readLines():
process_line(line) ...
당신이 쓰는 것이 귀하의 프로토콜(어쩌면 하위 클래스 a twisted.protocols.basic.LineReceiver
):
class MyProtocol(LineReceiver):
...
def lineReceived(self, line):
process_line(line) ...
당신이 원하는 형식의 코드를 사용하여 lineReceived
콜백을 보다가 반복되는 반복입니다.
당신이 무슨 글:
for line in self.twistedTcpClient.readLines():
process_line(line) ...
은 문제가 있으로 꼬이 비동기적으로 수행됩니다.방법은 없을 위한 꼬이는 주위에 얻을하고 아무것도 다른 사람을 기다리는 동안 twistedTcpClient.readLines()
방법입니다.
내 건 쓰 프로토콜,그러나 당신이 정말로 주장한 데에 이 반복 패턴,다음 수 있습니다 이렇게하려면:
@inlineCallbacks
def my_func():
while True:
try:
line = yield self.twistedTcpClient.getNextLine()
except StopIteration:
break
process_line(line) ...
지금 까다로운 것을 만드는 것입 twistedTcpClient
return Deferreds
각 통화를 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())
(이것은 단지 예를 보여주는 아이디어,당신은 그것을 확장하여 세부 사항을 처리 할 수 있습니다.)