我正在使用 JAXL 库来实现一个用 php 编写的 jabber 聊天机器人,然后使用 PHP CLI 作为后台进程运行。
一切都很好,但我一直很难弄清楚如何让聊天机器人在断开连接时重新连接!
我注意到当我让它整夜运行时,它有时会掉下来并且不会回来。我已经在 jaxl_post_disconnect 挂钩之后尝试了 $jaxl->connect() 和 $jaxl->startStream(),以及 $jaxl->startCore(),但我认为我遗漏了一些东西。
一种解决方案是测试您的连接:
1) making a "ping" request to your page/controller or whatever
2) setTimeout(functionAjaxPing(), 10000);
3) then read the Ajax response and if == "anyStringKey" then your connection works find
4) else: reconnect() / errorMessage() / whatEver()
我认为这就是 IRC 聊天的用途。
但这会产生更多流量,因为需要 ping/ping 请求。
跳这会帮助你一点。:)
如果您使用的是 Jaxl v3.x,您只需为on_disconnect
event添加一个回调。
此外,您必须使用XEP-0199 XMPP Ping。这个 XEP 将做的是定期向连接的 jabber 服务器发送 XMPP ping。它还将接收服务器 ping 并发送回所需的 pong 数据包(例如,如果您的客户端没有回复服务器 ping,jabber.org 将在一段时间后断开您的连接)。
最后,您还必须使用空格 ping。空白 ping 是发送到服务器的单个空格字符。这通常足以使 NAT 设备认为连接“活动”,对于某些 Jabber 服务器也是如此,例如 Openfire。它还可以使操作系统更快地检测到丢失的连接——没有数据发送或接收的 TCP 连接与丢失的连接无法区分。
我最终做的是创建一个简单地再次执行 PHP 脚本的 crontab。
在 PHP 脚本中,我读取了最后一个分叉的 pid 的特定文件。如果它存在,脚本会尝试杀死它。然后脚本使用 pcntl_fork() 来分叉进程(无论如何这对于守护 PHP 脚本很有用)并将新的 PID 捕获到文件中。然后,fork 按照惯例使用 JAXL 登录到 Jabber。
在与 JAXL 的作者交谈后,很明显这将是解决此问题的最简单方法,尽管它很 hacky。然而,作者可能已经在最近的迭代中解决了这个特定的缺陷。
这种特定方法的一个缺陷是它需要默认情况下不使用 PHP 编译的 pcntl_fork()。