私はHapiフレームワークでnode.jsサーバーを開発しています。私はRabbitMQ(amqp)を採用して私の仕事を待ちました。ただし、リクエストが送信されるとすぐにリクエストに返信するのではなく、実際の機能がコンシューマとして設定されているRabbitサーバにメッセージが送信されます。次に、消費者は結果を(要求、応答)関数に戻し、関数に応答させる必要があります。Node.jsスクリプト間のデータ転送
私の解決策は、私のワーカーファイル(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を登録するにはどうすればいいですか? – zhangjinzhou