2008-11-24 8 views
23

Tôi đang tìm cách gửi định kỳ một số dữ liệu trên tất cả các máy khách được kết nối với cổng TCP. Tôi đang nhìn vào python xoắn và tôi biết về reactor.callLater. Nhưng làm thế nào để sử dụng nó để gửi một số dữ liệu đến tất cả các khách hàng được kết nối định kỳ? Logic gửi dữ liệu nằm trong lớp Protocol và nó được khởi tạo bởi lò phản ứng khi cần thiết. Tôi không biết làm thế nào để buộc nó từ lò phản ứng cho tất cả các trường hợp giao thức ...Chạy chức năng định kỳ trong giao thức bị xoắn

Trả lời

37

Bạn có thể muốn thực hiện việc này trong Nhà máy để kết nối. Nhà máy không tự động được thông báo mỗi khi kết nối được thực hiện và bị mất, vì vậy bạn có thể thông báo cho nhà máy từ Nghị định thư.

Dưới đây là ví dụ hoàn chỉnh về cách sử dụng twisted.internet.task.LoopingCall kết hợp với Nhà máy và Giao thức cơ bản tùy chỉnh để thông báo rằng '10 giây đã trôi qua 'cho mọi kết nối cứ 10 giây một lần.

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

Cảm ơn! Điều này đã giúp rất nhiều. Tôi đã cố gắng xử lý việc gửi dữ liệu trong lớp giao thức và gặp sự cố khi xử lý không có quyền truy cập vào tất cả các máy khách (có một lớp đơn lẻ để giữ tất cả chúng!)! Làm điều này trong phân lớp nhà máy có ý nghĩa hơn rất nhiều. Tôi sẽ viết lại mã của tôi ... Cảm ơn! – Amit

+0

Làm cách nào để bạn viết một bài kiểm tra để xác minh rằng khách hàng nhận được "* 10 giây đã trôi qua \ n *" sáu lần trong một phút? – Sardathrion

3

Tôi muốn tưởng tượng cách dễ nhất để làm điều đó là quản lý danh sách khách hàng trong giao thức với connectionMade và connectionLost trong máy khách và sau đó sử dụng LoopingCall để yêu cầu mỗi khách hàng gửi dữ liệu.

Điều đó cảm thấy một chút xâm lấn, nhưng tôi không nghĩ rằng bạn muốn làm điều đó mà không có giao thức kiểm soát việc truyền/nhận. Tất nhiên, tôi phải xem mã của bạn để thực sự biết nó phù hợp như thế nào. Có một liên kết github? :)

+0

Tôi đã nhận phiên bản ban đầu. Reactor.callLater có thể được gọi bất cứ nơi nào, vì vậy tôi đã gọi nó từ connectionMade(). Tuy nhiên, bây giờ vấn đề là mọi kết nối đều có bộ đếm thời gian và dữ liệu riêng. Tôi thực sự muốn có một bộ đếm thời gian và dữ liệu. (như phát sóng) ... – Amit