我正在实现一个基于 Twisted 的心跳客户端/服务器组合,基于这个例子。这是我的第一个 Twisted 项目。
基本上它由一个 UDP 侦听器 ( ) 组成,它在接收包时Receiver
调用侦听器方法 ( )。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
所以我需要在我的 DetectorService 中添加某种额外的服务器(Socket、Tcp、RPC - 没关系。重点是我能够构建具有上述行为的客户端脚本),它允许从外部连接到它。它应该只对请求做出响应。
该服务器需要访问正在运行的检测器服务实例的内部变量,所以我猜测我必须使用某种附加服务来扩展 DetectorService。
经过几个小时尝试将检测器服务与其他几个服务结合起来,我仍然不知道实现这种行为的最佳方法是什么。所以我希望有人能给我至少基本的提示如何开始解决这个问题。提前致谢!!!