繁体   English   中英

修改 Python 的 Pubnub 存在心跳

[英]Modifying Pubnub presence heartbeat for Python

根据在线文档,Pubnub 将在 5 分钟未收到心跳后触发超时在线事件。 我需要修改此值,但我找不到使用 Python SDK 执行此操作的方法。 这是一个指向 Pubnub 文档的链接,展示了如何使用 JavaScript 执行此操作: http ://www.pubnub.com/docs/web-javascript/presence#optimizing_timeout_events

有谁知道如何使用 python SDK 实现这一目标?

非常感谢。

编辑:我的客户不是 javascript 客户。 它们是 python 控制台应用程序。

PubNub Python SDK 存在

由于 Python 很少用作客户端PubNub Python SDKPresence API不像传统的客户端 SDK(JavaScript 等)那样健壮地实现。 因此,Pubnbub 初始化程序中没有心跳参数,也没有设置器属性,因此您必须坚持使用默认的 5 分钟心跳设置。

但是,对于PubNub JavaScript SDK ,当您使用自定义heartbeat (例如 60 秒)初始化 PUBNUB 时, heartbeat键/值只是作为 REST URL 中的查询参数传递:

http://pubsub.pubnub.com/subscribe/demo/my_channel/0/14411482999795083?uuid=12345&pnsdk=PubNub-JS-Web%2F3.7.14&heartbeat=60

因此,如果您真的想要,您可以使用 REST 调用订阅并以这种方式传递heartbeat

我第一次发布此答案时忘记提及的是,您的客户端负责至少每 60 秒 ping PubNub 服务器一次,最好每隔 30 秒,这是服务器为此客户端配置的 60 秒心跳窗口。

使用 PubNub SDK,这是在同一连接上的单独线程中完成的(某种程度上 - 至少在某种程度上,服务器知道它是设置心跳的同一客户端)。

也就是说,我们正在使用 REST 进入一个不那么琐碎的解决方案,所以为什么还要使用 SDK。 更新 Python SDK 对我们来说比你做所有脏活要容易。 我们会做到这一点,但不是在短期内,而是希望在 Python SDK 的下一个次要版本中。

根据我们的 off-SO 对话,您只想缩短客户端看起来在线的时间窗口,而实际上客户端未连接并且在连接关闭之前无法明确取消订阅(关闭终端而不是使用应用程序的 UI 或命令行“注销”)。

您可以做的是实现ping/ack握手协议。 这是非常高的水平,因此可能需要填写一些更精细的点,但它应该提供一般概念。

  • 在一个客户端(发送者)与另一个(接收者)进行通信之前,只需在客户端的私有频道上向另一个客户端发送ping消息(每个客户端都将订阅该客户端独有的频道:例如,private_client001、private_client002 等.)
  • 接收客户端将自动确认发送方的唯一通道(这将是 ping msg 有效负载的一部分)
  • 如果 ping 的发送方在一秒钟内没有收到 ack msg(或任何适合您的时间容限),则假设接收方不在线。
  • 当接收者重新上线时,您会收到错过的消息,以及任何不到 5 分钟的ping ,您可以回复并查看发送者是否仍想参与。

这是许多用例(尤其是聊天)的常见问题,因为总是有一个时间窗口(心跳窗口),客户端可能真的离线但看起来在线,因为他们没有以适当的、可预测的方式离开产生了导致leave事件的显式unsubscribe 所以实现这种握手预连接协议是一个很好的做法。

Heartbeat 可以通过如下方式修补到Pubnub类中:

from pubnub import Pubnub

class PubnubHeartbeat(Pubnub):
    def __init__(self, heartbeat=300, **kwargs):
        self.heartbeat = heartbeat
        super(PubnubHeartbeat, self).__init__(**kwargs)

    def getUrl(self, request):
        if "subscribe" in request['urlcomponents'][:2]:
            if "urlparams" not in request:
                request['urlparams'] = {}
            request['urlparams']['heartbeat'] = self.heartbeat

        return super(PubnubHeartbeat, self).getUrl(request)


p = PubnubHeartbeat(
    subscribe_key="demo",
    publish_key="demo",
    heartbeat=60
)

def recv(msg):
    print msg

p.subscribe(channels="heartbeat_test", callback=recv)

这不推荐用于长期生产代码(除非您在安装期间使用pubnub==3.7.3固定您的 Pubnub 依赖pubnub==3.7.3 )。 示例子类使用未公开的方法注入heartbeat URL 参数。 (有关其作用的描述,请参阅 Craig Conover 的回答)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM