我们有一个 xmpp 连接服务器,它将套接字连接到 GCM XMPP 端点并开始发送通知。
我们注意到的一件事是发送半大通知(例如少至 1000 个设备)时,套接字会突然断开连接收到以下错误消息:
Client disconnected socket=b913-512-904dc69, code=EPIPE, errno=EPIPE, syscall=write
例如,这是实时服务器开始向不同注册IDS发送通知时的日志。
- 信息:发送下游消息 msgId=P#c1uq...socketId=512
- 信息:发送下游消息 msgId=P#c3tE...socketId=512
- 信息:发送下游消息 msgId=P#c1TF...socketId=512
- 信息:发送下游消息 msgId=P#c3sy...socketId=512
- info: Sent downstream message msgId=P#c41N... socketId=512
...
- 信息:发送下游消息 msgId=P#cJbr...socketId=512
- 信息:发送下游消息 msgId=P#cJXO...socketId=512
信息:客户端断开连接套接字 = b913-512-904dc69,代码 = EPIPE,errno = EPIPE,
系统调用=写
这种情况在我们的系统中时时处处不断发生,使得服务质量检查变得非常困难。
我们注意到的另一件事是有时打电话时socket.send(stanza)
, 价值false
被返回,即使套接字确实已连接。这一点更糟糕,因为我们必须对消息进行重新排队,并且在发送数百万条消息时确实会占用大量资源。这将在下面解释。
附加信息:
从第 1 条消息到第 84 条(发生断开连接),更少
已经过去了不到 100 毫秒。
我们为这个 JID/PASSWORD 打开了大约 52 个套接字
(GCM 术语中的 senderId、Api_key),位于 3 个不同的服务器上。全部保留
当有大的通知发送任务到来时,时不时地断开连接
一起(比如 10000 个收件人)。
- 套接字成功重新连接,但它们断开了几秒钟,这降低了我们系统的效率和可靠性。
连接如何设置:
const xmpp = require('node-xmpp-client');
let socket = new xmpp.Client({
port: 5235,
host: 'gcm-xmpp.googleapis.com',
legacySSL: true,
preferredSaslMechanism: 'PLAIN',
reconnect: true,
jid: $JID,
password: $PASSWORD
});
socket.connection.socket.setTimeout(0);
socket.connection.socket.setKeepAlive(true, 10000);
socket.on('stanza', (stanza) => handleStanza(stanza));
...
为收到的每个上游消息发送确认。
但我们看到的一件事是发送下游消息时,以下有时会返回 false,“即使套接字已连接”.
// This returns false many times! even when the socket.connection.connected === true!
socket.send(xmppStanza)
如果发生这种情况,我们会将 ack 消息排队以便稍后重试,但继续向 gcm 发送消息。
为什么socket.send
有时返回 false ? (这显然不是像 EPIPE 或其他什么错误,它只是一个错误,意味着刷新套接字不成功,也许套接字变得不可写,即使它已连接?)。
如果确认延迟,GCM 会关闭与延迟确认的连接还是会停止向上游发送?
(据我所知,它只会停止向上游发送,所以这可能与关闭连接(EPIPE)无关?)
如果有人能够阐明这种行为,我将非常感激。
Thanks !