2008-11-24 3 views
23

TCP 포트에 연결된 모든 클라이언트를 통해 주기적으로 데이터를 보내는 방법을 찾고 있습니다. 나는 꼬인 파이썬을보고 있는데 reactor.callLater를 알고있다. 하지만 어떻게하면 모든 연결된 클라이언트에게 데이터를 주기적으로 보낼 수 있습니까? 데이터 전송 로직은 프로토콜 클래스에 있으며 필요에 따라 반응기에 의해 인스턴스화됩니다. 원자로에서 모든 프로토콜 인스턴스로 묶는 방법을 모르겠다. ...꼬인 프로토콜로 함수를 주기적으로 실행하기

답변

37

아마 당신은 공장에서 연결을 원할 것입니다. 팩토리는 연결이 끊어 지거나 끊어 질 때마다 자동으로 통보되지 않으므로 프로토콜에서 통보 할 수 있습니다.

twisted.internet.task.LoopingCall을 사용자 지정 기본 팩토리 및 프로토콜과 함께 사용하여 10 초마다 모든 연결에 '10 초가 경과 한 '것을 알리는 방법의 전체 예제입니다.

from twisted.internet import reactor, protocol, task 

class MyProtocol(protocol.Protocol): 
    def connectionMade(self): 
     self.factory.clientConnectionMade(self) 
    def connectionLost(self, reason): 
     self.factory.clientConnectionLost(self) 

class MyFactory(protocol.Factory): 
    protocol = MyProtocol 
    def __init__(self): 
     self.clients = [] 
     self.lc = task.LoopingCall(self.announce) 
     self.lc.start(10) 

    def announce(self): 
     for client in self.clients: 
      client.transport.write("10 seconds has passed\n") 

    def clientConnectionMade(self, client): 
     self.clients.append(client) 

    def clientConnectionLost(self, client): 
     self.clients.remove(client) 

myfactory = MyFactory() 
reactor.listenTCP(9000, myfactory) 
reactor.run() 
+0

고마워! 이것은 많은 도움이되었습니다. 나는 프로토콜 클래스에서 데이터를 보내는 것을 처리하려고 시도하고 있었고 모든 클라이언트에 액세스하지 못하는 문제를 겪고있었습니다 (모든 것을 잡는 싱글 톤 클래스가있었습니다!)! 공장 하위 클래스에서이를 수행하는 것이 훨씬 더 의미가 있습니다. 내 코드를 다시 작성하겠습니다 ... 고마워! – Amit

+0

클라이언트가 "* 10 초가 \ n *"분당 6 번 도달하는지 확인하는 테스트를 작성 하시겠습니까? – Sardathrion

3

가장 쉬운 방법은 클라이언트의 connectionMade 및 connectionLost를 사용하여 프로토콜에서 클라이언트 목록을 관리하는 것입니다. LoopingCall을 사용하여 각 클라이언트에게 데이터를 보내도록 요청하십시오.

약간 침해가 느껴지지만 전송/수신에 대한 일부 제어가없는 프로토콜을 사용하고 싶지는 않습니다. 물론, 코드가 실제로 어떻게 잘 들어 맞는지 실제로 알 수 있어야합니다. github 링크가 있습니까? :)

+0

초기 버전이 작동했습니다. reactor.callLater는 어디에서든지 호출 할 수 있으므로 connectionMade()에서 호출해야합니다. 그러나 이제 문제는 모든 연결에 자체 타이머와 데이터가 있다는 것입니다. 나는 정말로 하나의 타이머와 데이터를 원할 것이다. (방송과 같은) ... – Amit

관련 문제