この例に基づいて、ツイストベースのハートビートクライアント/サーバーコンボを実装しています。それは私の最初のツイストプロジェクトです。
基本的には、パッケージの受信時にReceiver
リスナーメソッド()を呼び出すUDPリスナー( )で構成されます。DetectorService.update
DetectorServiceは、現在アクティブ/非アクティブなクライアントのリストを常に保持し(例を大幅に拡張しましたが、コアは同じです)、指定されたタイムアウトで切断されたように見えるクライアントに対応できるようにします。
これは、サイトから取得したソースです。
UDP_PORT = 43278; CHECK_PERIOD = 20; CHECK_TIMEOUT = 15
import time
from twisted.application import internet, service
from twisted.internet import protocol
from twisted.python import log
class Receiver(protocol.DatagramProtocol):
"""Receive UDP packets and log them in the clients dictionary"""
def datagramReceived(self, data, (ip, port)):
if data == 'PyHB':
self.callback(ip)
class DetectorService(internet.TimerService):
"""Detect clients not sending heartbeats for too long"""
def __init__(self):
internet.TimerService.__init__(self, CHECK_PERIOD, self.detect)
self.beats = {}
def update(self, ip):
self.beats[ip] = time.time()
def detect(self):
"""Log a list of clients with heartbeat older than CHECK_TIMEOUT"""
limit = time.time() - CHECK_TIMEOUT
silent = [ip for (ip, ipTime) in self.beats.items() if ipTime < limit]
log.msg('Silent clients: %s' % silent)
application = service.Application('Heartbeat')
# define and link the silent clients' detector service
detectorSvc = DetectorService()
detectorSvc.setServiceParent(application)
# create an instance of the Receiver protocol, and give it the callback
receiver = Receiver()
receiver.callback = detectorSvc.update
# define and link the UDP server service, passing the receiver in
udpServer = internet.UDPServer(UDP_PORT, receiver)
udpServer.setServiceParent(application)
# each service is started automatically by Twisted at launch time
log.msg('Asynchronous heartbeat server listening on port %d\n'
'press Ctrl-C to stop\n' % UDP_PORT)
このハートビートサーバーは、バックグラウンドでデーモンとして実行されます。
今私の問題:
スクリプトを「外部」で実行して、レシーバーが存続期間中に収集するオフライン/オンラインクライアントの数をコンソールに出力できるようにする必要があります(self.beats
)。このような:
$ pyhb showactiveclients
3 clients online
$ pyhb showofflineclients
1 client offline
したがって、ある種の追加サーバー(Socket、Tcp、RPC-関係ありません。主なポイントは、上記の動作でクライアントスクリプトを作成できることです)をDetectorServiceに追加する必要があります。これにより、次のことが可能になります。外部から接続します。リクエストに応答するだけです。
このサーバーは、実行中のdetectorserviceインスタンスの内部変数にアクセスできる必要があるため、DetectorServiceを何らかの追加サービスで拡張する必要があると思います。
検出器サービスを他のいくつかのサービスと組み合わせようとして数時間経っても、その動作を実現するための最良の方法がまだわかりません。ですから、誰かが私に少なくともこの問題を解決し始めるための本質的なヒントを与えてくれることを願っています。前もって感謝します!!!