PHP Client for Apple Push Notification Service

源码在:https://github.com/sskaje/apns

协议消息体使用的是APNS的简版消息结构,暂不支持Enhanced notification format,即不支持identifier和expiry,省了8个字节,不过稍后有空会加上。

大致的数据逻辑是:

走了个异步队列。应用将推送数据按公用结构(适配非APNS的推送需求)带上推送的目标设备类型+客户端标识(支持同平台下多款应用的推送)所用的队列;后端程序阻塞或非阻塞的模式从队列里取数据,然后根据数据信息写APNS或者其他类型终端(例如Android)的推送服务。

开发过程中遇到的最大问题主要在 stream_socket_client() 的 STREAM_CLIENT_PERSISTENT 使用上:


最早需求上只有一个客户端证书的需求,不需要做切换,只需要创建一个连接,context配好证书,不论存不存静态变量,直接用就是了。

但是后来公司有第二个客户端的推送需求,简单地上了一个static变量,意图直接两个静态对象再根据数据参数选择连接,但是结果发现消息丢失率大大提升,而且两个客户端的推送消息还互串。

php源码的 ext/standard/streamfuncs.c

而 main/streams/php_stream_transport.h

显然直接使用了 host 参数拼了个字符串就当persistent id了。而现在的需求又不得不使用两个证书创建不同的连接,于是解决方案似乎不外乎 干掉 STREAM_CLIENT_PERSISTENT 或者 拆分推送脚本 要不就得直接改源码了。

当然,直接使用IP(譬如一个使用域名一个使用IP,或者直接用上域名的一片A记录,每种客户端需求使用不同的IP连接),看似也是个解决方案,但是带来的灾难比拆分推送脚本还大。

偶然想到一个没准可行的解决方案:
ssl://gateway.push.apple.com:2195/?xxx
xxx部分可以用证书路径做个md5什么的,反正是个ssl socket连接,没有path和query的需求,应该能可用,而且还能区分成不同的’host’参数。
github里的代码是按这个想法本地实验过验证可行了的,只是生产环境的具体情况还得观察。

PHP Client for Apple Push Notification Service by @sskaje: https://sskaje.me/2012/11/apns-client/