当前位置: 首页 > 知识库问答 >
问题:

Nodejs-设置体到谷歌云任务队列

湛光明
2023-03-14

我在谷歌应用程序引擎中有一个nodejs服务器,我想使用谷歌云任务队列将长时间运行的任务委托给任务队列。

任务队列未传递请求正文,但到达终结点:

以下是我将任务添加到任务队列的方式:

// Imports the Google Cloud Tasks library.
const cloudTasks = require('@google-cloud/tasks');

// Instantiates a client.
const client = new cloudTasks.CloudTasksClient();
const project = 'projectname';
const queue = 'queuename';
const location = 'us-central1';
const parent = client.queuePath(project, location, queue);

// Send create task request.
exports.sender = async function (options) {
// Construct the fully qualified queue name.
    let myMap = new Map();
    myMap.set("Content-Type", "application/json");
    const task = {
        appEngineHttpRequest: {
            httpMethod: 'POST',
            relativeUri: '/log_payload',
            headers: myMap,
            body: options/* Buffer.from(JSON.stringify(options)).toString('base64')*/
        },
    };
    
    /* if (options.payload !== undefined) {
         task.appEngineHttpRequest.body = Buffer.from(options.payload).toString(
           'base64'
         );
     }*/
    
    if (options.inSeconds !== undefined) {
        task.scheduleTime = {
            seconds: options.inSeconds + Date.now() / 1000,
        };
    }
    
    const request = {
        parent: parent,
        task: task,
    };
    client.createTask(request)
      .then(response => {
          const task = response[0].name;
          //console.log(`Created task ${task}`);
          return {'Response': String(response)}
      })
      .catch(err => {
          //console.error(`Error in createTask: ${err.message || err}`);
          return `Error in createTask: ${err.message || err}`;
      });
};

这是接收的endpoint:

app.post('/log_payload', async (req, res) => {
    let mailOptions = {
        subject: 'Message Delivered',
        from: 'sender@example.com',
        to: "receiver@example.com",
        text: String(JSON.stringify(JSON.stringify(req.body)))
    };
    return await mailer.sendEmail(mailOptions).then(value => {
        return res.send(`Received task payload: ${value}`).end()
    }).catch(reason => {
        res.send(`Worker error: ${reason.message}`).end()
    });
});

当收到电子邮件时,两个主体都是空的Json对象。我做错了什么?

共有2个答案

班宏毅
2023-03-14

在这个示例的指导下,我认为从请求中解析主体的最佳方法是使用主体解析器包。

您可以通过更改接收endpoint文件来实现这一点,包括以下内容:

const bodyParser = require('body-parser');

app.use(bodyParser.raw());
app.use(bodyParser.json());
app.use(bodyParser.text());

app.post('/log_payload', async (req, res) => {
    let mailOptions = {
        subject: 'Message Delivered',
        from: 'sender@example.com',
        to: "receiver@example.com",
        text: req.body
    };
    return await mailer.sendEmail(mailOptions).then(value => {
        return res.send(`Received task payload: ${value}`).end()
    }).catch(reason => {
        res.send(`Worker error: ${reason.message}`).end()
    });
});
傅元龙
2023-03-14

只是为了补充琼·格劳的回答:

如果您添加此过滤器,您可以确保结果将被正确解析:

var bodyParser = require('body-parser');
var rawBodySaver = function (req, res, buf, encoding) {
  if (buf && buf.length) {
    req.rawBody = buf.toString(encoding || 'utf8');
  }
}

app.use(bodyParser.json({ verify: rawBodySaver }));
app.use(bodyParser.urlencoded({ verify: rawBodySaver, extended: true }));
app.use(bodyParser.raw({ verify: rawBodySaver, type: function () { return true } }));

(这篇文章的想法)

特别是,一个好的做法是将解析器应用到您需要的任何地方。此外,考虑将基本64字符串发送到主体内容(这是云任务工作所必需的)。用所有这些重写代码:

const task = {
        appEngineHttpRequest: {
            httpMethod: 'POST',
            relativeUri: '/log_payload',
            headers: myMap,
            body: Buffer.from(JSON.stringify(options)).toString('base64')
        },
    };

终点是:

var bodyParser = require('body-parser');
var rawBodySaver = function (req, res, buf, encoding) {
  if (buf && buf.length) {
    req.rawBody = buf.toString(encoding || 'utf8');
  }
}

app.use('/log_payload', bodyParser.json({ verify: rawBodySaver }));
app.use('/log_payload', bodyParser.urlencoded({ verify: rawBodySaver, extended: true }));
app.use('/log_payload', bodyParser.raw({ verify: rawBodySaver, type: function () { return true } }));

app.post('/log_payload', async (req, res) => {
    let mailOptions = {
        subject: 'Message Delivered',
        from: 'sender@example.com',
        to: "receiver@example.com",
        text: req.body //no need to parse here!
    };
    return await mailer.sendEmail(mailOptions).then(value => {
        return res.send(`Received task payload: ${value}`).end()
    }).catch(reason => {
        res.send(`Worker error: ${reason.message}`).end()
    });
});
 类似资料:
  • 介绍如何在谷歌云平台获取在云联壹云平台需要使用的配置参数。 如何获取谷歌云服务帐号密钥信息? 纳管指定项目 打开“GCP Console中的IAM和管理-IAM页面”页面并登录。 单击顶部“选择项目”,选择需要授权的项目。 在左侧导航栏中选择“服务账号”,进入指定项目的服务账号页面。 单击 “创建服务账号” 按钮,进入创建服务账号页面。 配置服务账号名称、服务账号ID、服务账号说明等,单击 “创建

  • 上面写着“Google Cloud Messaging(GCM)是一个免费服务”,但是为了使它能够运行,我需要在Google Cloud平台中创建一个项目,这需要花钱…那怎么免费呢?还是我错过了什么?

  • 我想创建一个应用程序,在后端我想写代码node.js谷歌云平台支持node.js? 我可以看到只有Python,Java,PHP和GO支持。

  • 我正在向gcs写入一些字节,并希望使用谷歌提供的JSON API包装器,但有一个超时。目前我有: 有没有一种简单的方法可以向、或?

  • 亚马逊通过CloudFront SNI允许这样做。