【问题标题】:Node.js transport data between scriptsNode.js 在脚本之间传输数据
【发布时间】:2017-02-23 00:10:49
【问题描述】:

我正在 Hapi 框架中开发一个 node.js 服务器。我采用 RabbitMQ (amqp) 对我的任务进行排队。但是,一旦发送请求,而不是立即回复请求,消息将被发送到 Rabbit 服务器,实际功能作为消费者所在的位置。然后,消费者应该将结果返回给(请求,回复)函数并让函数回复它。

现在我的解决方案是在我的工作文件(amqp 消费者所在的位置)中创建一个变量并将其导出。然后在索引文件(我的带有路由处理程序的主脚本)中,我导入了变量。一旦收到某个请求,它将向 RabbitMQ 服务器发送一条消息,服务器将更改该变量。然后,回到索引文件,脚本更新变量的值,然后回复它。显然,由于异步,程序会回复先前请求的结果。

我做了一些研究,发现我们不应该在脚本之间共享某些变量。有没有人有办法解决吗?我的目标是我可以将我的 amqp 消费者放在一个脚本中。一旦我运行脚本,消费者将准备好接收任何相应的消息。然后在我的索引文件中,一旦收到一些请求,它就会向 RabbitMQ 服务器发送一条消息。然后它应该抓取消费者的结果并回复它。

下面是我的代码:

index.ts

import * as Joi from "joi";
import * as amqp from "amqplib/callback_api";
import * as waitUntil from "wait-until";

import * as repository from "./repository";
import * as worker from "./worker";

// defien variables from internal modules
let greeter = new repository.Greeter();

// register type
import {Register} from "../../interfaces";

// define amqp related stuff
let greeterReply = worker.greeterReply;

// helloWorld config including handler, validate and auth
export let register: Register = (server, options, next) => {
    server.route([
    {
        method: "GET",
        path: "/greeter",
        config: {
            handler: (request, reply) => {
                let q: string = "greeter";
                let requestQuery = request.query;
                let requestString = JSON.stringify(requestQuery);
                amqp.connect("amqp://192.168.0.31", (err, conn) => {
                    conn.createChannel((err, ch) => {
                        ch.assertQueue(q, {durable: false});
                        ch.sendToQueue(q, new Buffer(requestString));
                    });
                });
                waitUntil(500, 10, function condition() {
                    greeterReply = worker.greeterReply;
                    return (greeterReply !== null);
                }, function done(result) {
                    reply(greeterReply);
                    greeterReply = null;
                });
            },
            validate: {
                query: {
                    name: Joi.string(),
                    age: Joi.number()
                }
            },
        }
    }
    ]);
    next();
};

register.attributes = {
    name: "greeter",
    version: "1.0"
};

worker.ts

// import external modules
import * as amqp from "amqplib/callback_api";

// import internal modules
import * as repository from "./repository";
import * as indexModule from "./index";

// defien variables from internal modules
let greeter = new repository.Greeter();

export let greeterReply = null;

amqp.connect("amqp://192.168.0.31", (err, conn) => {
    conn.createChannel((err, ch) => {
        let q: string = "greeter";
        ch.assertQueue(q, {durable: false});
        ch.consume(q, function (requestString)  {
            let newRequest = JSON.parse(requestString.content.toString());
            console.log("replied via amqp");
            let result: string = "how are you";
            result = greeter.helloWorld(newRequest.name, newRequest.age);
            console.log("the result is: ", result);
            greeterReply = result;
        }, {noAck: true});
    });
});

【问题讨论】:

  • 看看插件来封装这类东西。还要在工作函数中使用回调来触发和控制处理。通过使用类,您可以封装每个请求的状态,但是如果您想要高吞吐量,这最终可能会成为一个问题。
  • 如果我使用回调函数,我必须调用索引文件中的函数对吗?这不是我打算做的。我确实有很多路线要处理。你能详细解释一下插件方法吗?如何将 amqp 注册为插件?

标签: javascript node.js rabbitmq hapijs


【解决方案1】:

您需要的是一种基于 RabbitMQ 的 RPC。 RabbitMQ 支持它,如tutorials here 中所示。

您可以使用您已经在使用的amqplib 自己实现它,也可以使用像amqp-rpc 这样的特定模块来为您实现。

【讨论】:

  • 我相信这就是解决方案!比你哥们但是,如果不使用 RPC,我注意到如果我不在终端中运行 worker,我的程序(上面的代码)可以正常工作。当发布者发送消息时,看起来消费者作为子进程运行。你知道原因吗? @tbking
  • 那是因为你已经导入了worker文件,也就是说你只需要运行index文件,它就会运行worker文件并调用你自己的worker。你的代码是这样的,你不需要单独运行这些文件。
  • 谢谢!在这种情况下,你认为我还需要使用 RPC 吗?如果可以,我能得到什么好处?
  • 嗯,这样做的好处是您的 master 和 worker 将彼此完全解耦。现在,您的 master 依赖于同一目录中名为 worker.js 的文件。如果您重命名工作文件,您也必须更改 index.js 中的代码。在 RPC 中,它们都完全不知道彼此。也可以有多个工人。师父不需要知道。它们可以放置在通过 Internet 上的 RPC 连接的不同系统中。所以使用它总是好的。您必须决定是否需要。
  • 谢谢@tbking!我已经申请了。我可以看到好处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-04
  • 1970-01-01
  • 2021-06-01
  • 2011-01-19
  • 1970-01-01
  • 2013-09-10
  • 1970-01-01
相关资源
最近更新 更多