发出请求时出错:套接字挂起。错误代码:ECONNRESET

时间:2019-12-08 07:16:40

标签: firebase econnreset

我将node.js用作后端服务器,用于从Firebase Cloud Messaging服务发送推送通知。通知在本地服务器上运行正常,但在实时服务器上,出现此错误:

  

发出请求时出错:套接字挂起。错误代码:ECONNRESET

要考虑的是...

  • 实时服务器上的用户数为数千
  • Firebase版本为firebase-admin@6.5.1
  • 以前未注册的令牌仍然存在。但是现在已存储已注册的令牌。

这是我发送通知的代码:

for (let c = 0; c < tokens.length; c++) 
{
    let notifyTo = tokens[c];
    const platform = platforms[c];

    let payload;
    if (platform === "ios") {
        payload = {
            notification: {
                title: "title",
                subtitle :"messgae",
                sound: "default",
                badge: "1"
            },
            data: {
                sendFrom: "",
                notificationType: "",
                flag: "true"
            }
        };
    } else if (platform === "android") {
        payload = {
            data: {
                title: "",
                message : "",
                flag: "true"
            }
        };
    }

    const registrationtoken = notifyTo;

    await admin.messaging().sendToDevice(registrationtoken, payload)
        .then(function (response) {
            console.log("Successfully sent message:");
        })
        .catch(function (error) {
            console.log("Error sending message: ");
        });
}

1 个答案:

答案 0 :(得分:0)

您的问题是由您的函数对客户端做出的响应时间过长(超过60秒)引起的,并且是由以下行引起的:

await admin.messaging().sendToDevice(registrationtoken, payload)

由于您正在分别等待sendToDevice()的每次调用,因此您以同步顺序而不是异步并行地运行for循环。

为避免这种情况,您想利用数组映射和Promise.all()来建立sendToDevice()请求队列。就像您当前的代码一样,所有失败的消息都将被静默忽略,但我们也会对它们进行计数。

您当前的代码使用两个数组tokensplatforms,因此在下面的代码中,我为Array.prototype.map()使用了一个回调,该回调带有两个参数-当前映射值(来自tokens)及其索引(for循环的c值)。然后使用索引来获取正确的平台条目。

let fcmPromisesArray = tokens.map((token, idx) => {
    let platform = platforms[idx];

    if (platform === "ios") {
        payload = {
            notification: {
                title: "title",
                subtitle :"messgae",
                sound: "default",
                badge: "1"
            },
            data: {
                sendFrom: "",
                notificationType: "",
                flag: "true"
            }
        };
    } else if (platform === "android") {
        payload = {
            data: {
                title: "",
                message : "",
                flag: "true"
            }
        };
    }

    return admin.messaging().sendToDevice(token, payload) // note: 'await' was changed to 'return' here
        .then(function (response) {
          return true; // success
        })
        .catch(function (error) {
            console.log("Error sending message to ", token);
            return false; // failed
        });
});

let results = await Promise.all(fcmPromisesArray); // wait here for all sendToDevice() requests to finish or fail
let successCount = results.reduce((acc, v) => v ? acc + 1 : acc, 0); // this minified line just counts the number of successful results

console.log(`Successfully sent messages to ${successCount}/${results.length} devices.`);

运行此代码段后,请不要忘记使用res.send(...)或类似的方法将结果发送回客户端。