NodeJS APN推送重复通知

0 投票
1 回答
592 浏览
提问于 2025-04-17 22:46

大家好,我最近在尝试用 Node.js 作为第三方的 APN 服务器,并且使用了 node-apn 这个模块(https://github.com/argon/node-apn)。当我在短时间内发送相同的通知(也就是说,发送相同的提示)时,比如在 5 分钟内发送 5 条通知,我发现苹果的 APN 服务器似乎“缓存”了我的通知。之后,当我正常发送另一条消息(以正常的速度,比如每 5 分钟发送一条)时,那些“缓存”的消息会一次又一次地发送到我的设备上。

我稍微研究了一下 node-apn 模块的代码,发现它是通过 TLS(SSL)连接到苹果的,并向苹果的服务器发送一个数据流(在 Node.js 中是一个 Buffer)。一切看起来都没问题,但当我在短时间内发送消息时,消息就是重复的。我还尝试了 Python 的库 APNSWrapper(https://code.google.com/p/apns-python-wrapper)。这个代码做的事情和 node-apn 一样,但问题并没有出现。

他们发送给苹果服务器的数据是完全相同的,包括:

[command, token.length, token.content, payload.length, payload.content]

其中,command、token.length 和 payload.length 是以双字节无符号整数的形式表示,采用 big-endian 格式。Python 库用格式 !HB32s58s 构造整个数据流,32 和 58 只是长度的表示。! 表示 big-endian,H 表示无符号字符(1 字节),B 表示无符号整数(2 字节)。32s 表示一个 32 字节的字符串,58 表示一个 58 字节的字符串。

而 Node.js 的 TLS 连接也是做同样的事情,所有的长度都是用 cleartextStream.writeUInt16BE() 写入的,这里的 BE 也是指 big-endian。

我逐字节测试过,他们发送的数据完全相同。我甚至创建了一个 SSL 服务器来接收他们的消息,结果我收到了相同的数据(也逐字节检查过)。所以苹果的服务器接收到的数据应该是完全一样的。但它们的行为却不同。我在这里等待任何建议,提前谢谢大家!

1 个回答

0

为了确保你不会重复发送,可以尝试以下方法:

apnConnection.on('transmitted', function(notification, device) {
  console.log("Notification transmitted to:" + device.token.toString('hex'));
});

撰写回答