如何在继承自pb.Root的服务器中检测丢失的客户端连接?

4 投票
1 回答
778 浏览
提问于 2025-04-15 18:47

比如,我有一个客户端,它是这样连接到服务器的:

class MyClientFactory(pb.PBClientFactory, ReconnectingClientFactory):
    def __init__(self):
        pb.PBClientFactory.__init__(self)
        self.ipaddress = None

    def clientConnectionMade(self, broker):
        log.msg('Started to connect.')
        pb.PBClientFactory.clientConnectionMade(self, broker)

    def buildProtocol(self, addr):
        log.msg('Connected to %s' % addr)
        return pb.PBClientFactory.buildProtocol(self, addr)

    def clientConnectionLost(self, connector, reason):
        log.msg('Lost connection.  Reason:', reason)
        ReconnectingClientFactory.clientConnectionLost(self, connector, reason)

    def clientConnectionFailed(self, connector, reason):
        log.msg('Connection failed. Reason:', reason)
        ReconnectingClientFactory.clientConnectionLost(self, connector, reason)

这样,客户端就能自动检测到连接是否丢失。

那么,如果客户端崩溃了,我该如何让服务器也能做到同样的检测呢?

目前,我是通过遍历一个可能连接的客户端列表来捕捉一个叫做DeadReferenceError的错误,但这种方法不是基于事件的,老实说,反应也太慢了。

欢迎任何想法。

提前谢谢大家。

1 个回答

4

你可以注册一个回调函数,这样当连接断开时就会被调用。这里有两个接口可以实现这个功能,一个是 Broker.notifyOnDisconnect,另一个是 RemoteReference.notifyOnDisconnect。它们的作用是一样的,不过根据你应用的具体情况,使用其中一个可能会更方便。

我不太确定你是否可以用这个来保证你永远不会遇到 DeadReferenceError(比如说,如果你的 remote_foo 方法被调用了,你返回了一个 Deferred,然后连接断开了,最后这个 Deferred 被触发,会发生什么我就不太清楚了),但至少在常见的情况下,你可以大大降低出现这种错误的可能性(也就是说,只要在 notifyOnDisconnect 调用你的函数之后不再使用 callRemote,你应该就能避免从 callRemote 中得到 DeadReferenceError)。

撰写回答