我有一个类似PHP服务器的脚本无限期运行。它使用PHP中的stream_socket_client对象连接到APNS( Apple推送通知服务)。
问题在于虽然大部分时间都可以使用,但是当我想发送推送通知时,我无法弄清楚如何验证与APNS的连接是否可用。该脚本接收传入连接并将内容复制到APNS。
当它不起作用时,脚本重新连接(写入0字节时stream_copy_to_stream的返回值为0,触发重新连接)然后下一个传入令牌将成功,但它会记录以下内容,当然不会传递消息:
PHP Warning: stream_copy_to_stream(): SSL: An established connection was
aborted by the software in your host machine.
有没有办法检测上述情况,从而在尝试写入套接字之前重新连接到APNS 。
在尝试复制到APNS之前执行此操作:
if (!$socketObject) {
// reconnect
}
不起作用,因为对象仍然存在(var_dump将打印描述)。那么如何检查连接是否仍然打开?
将任何内容写入不是有效令牌和有效负载的套接字将导致APNS断开连接。
执行写作的代码如下所示:
function writeToAPNS($client) {
return stream_copy_to_stream ( $client, $this->connectionAPNS );
}
从$client
返回stream_socket_accept ( $this->socket, -1 )
,$this->socket
是包含侦听传入连接的本地套接字对象的变量。 -1表示等待传入连接时没有超时。当它工作时,此函数返回写入的字节数。失败时返回0.
$this->connectionAPNS
是连接到APNS时从stream_socket_client
返回的对象。这是我在执行stream_copy_to_stream
函数之前要检查其有效性的原因。
所以基本上我想检测$this->connectionAPNS
是否有效。
我尝试转储连接对象的元数据,但它没有说明有效性,只要它超时,协议类型等。
答案 0 :(得分:1)
您是否在官方stream_socket_client文档中看到了此说明?
即使无法访问远程主机,UDP套接字有时也会在没有错误的情况下打开。 只有当您向套接字读取数据或从套接字写入数据时,错误才会显现。这是因为UDP是一种“无连接”协议,这意味着操作系统在实际需要发送或接收数据之前不会尝试为套接字建立链接。
请在您的连接上尝试此方法stream_get_meta_data以尝试检测差异。我现在无法测试它,但它可能对你有帮助。特别是 timed_out 属性。
至少将错误消息静音的另一个选项是,在处理它们时,是在stream_socket_client上设置适当的 errno 。
答案 1 :(得分:0)
嗯,正如M.K.所解释的那样,这就是UDP的工作原理。顺便说一下,你的代码是有效的。您的问题是警告,通过向您的写入函数添加@可以很容易地解决这个问题。 您的代码将如下所示:
function writeToAPNS($client) {
return @stream_copy_to_stream ( $client, $this->connectionAPNS );
}