あなたが何をする必要があるかの短いバージョンは、双方向メッセージングです。あなたのWebアプリケーションは、メッセージプロデューサとメッセージコンシューマである必要があります。バックエンドサービスにも同じことが言えます。
HTTPリクエストが到着すると、WebサーバーはRabbitMQを通じてメッセージを送信します。バックエンドは、将来、ある時点でそれをピックアップします。その間、ウェブサーバは何かが起こっていることをHTTPリクエストを介して返信し、後でユーザに通知する。
あなたは急行を使用している場合、それはこのようなものになります。
var router = express.Router();
router.post("/", postJob);
function postJob(req, res, next){
req.session.inProgress = true;
var msg = {
job: "do some work"
};
jobSender.sendJobRequest(msg, function(err){
if (err) { return next(err); }
res.render("some-response");
});
}
をこのコードは、jobSender
がRabbitMQの間でメッセージを送信する方法でカプセル化されたオブジェクトのいくつかの種類のもののように、仮定の多くを作ります。私はあなたがすでに言ったことに基づいて、メッセージを送信する詳細を記入できると確信しています。
重要なことは、HTTPリクエストハンドラがRabbitMQを介してメッセージを送信してから、HTTPレスポンスをWebブラウザに送信することです。
この時点で、ブラウザは必要な処理を行うことができます。
バックエンドには、他のサービスはそれが仕事だ完了したとき、それは2つのうちの1つ実行する必要があります。)
1をWebサーバーが持っているものの仕事を知っているように、どこかに共有データベースを更新RabbitMQの
オプション#1を介して、行われて(とステータス読むことができます)
または
2)バックWebサーバにメッセージを送信することは、常に様々な理由のために良いオプションではないかもしれません。あなたの質問から、あなたはオプション#2をとにかくしたい。
2番目のキュー(Webサーバーが待機しているキュー)が必要です。 Webサーバがこのキューからメッセージを受信すると、受信したステータスで自身のデータベースを更新します。
このステータスは、「完了」、「進行中」、「エラー」、またはそれ以外のものが表示されます。
たとえば、「ジョブステータス」というメッセージが表示されている場合は、ステータスメッセージを受け取るために「JobStatusReceiver」という抽象概念があるとします。
このような単純なモジュールは、ジョブ・ステータス・キューからメッセージを受信し、ステータスで、これはウェブサーバで何が起こってもよいことが
var JobStatusReceiver = require("./jobStatusReceiver");
var someDataObject = require("someDataObject");
var jobStatus = {
listen: function(){
var receiver = new JobStatusReceiver();
receiver.receive(function(statusMessage){
someDataObject.status = statusMessage.status;
someDataObject.data = statusMessage.data;
someDataObject.save();
});
}
};
module.exports = jobStatus;
ノートをローカルデータベースを更新するが、それはの一部ではありませんでしたHTTPリクエスト。メッセージはRabbitMQを介してJobStatusReceiverとともに送信され、HTTP要求の一部ではありません。
someDataObject
オブジェクトは、yoruデータベースのオブジェクトである可能性が高いため、データベースに戻すことができます。
最後に、完了した操作をユーザーに通知する必要がある部分は、さまざまな方法で発生する可能性があります。
一般的に言えば、有効な応答を探すために、数秒ごとにWebサーバー上のHTTP APIへのAJAX呼び出しを行うのはかなり簡単です。ブラウザ側で
、これはのような単純なものでした:取り扱い、エクスプレスアプリで
var timer = setInterval(function(){
$.ajax({
url: "/api/check-status",
success: function(data){
if (data.complete){
clearInterval(timer);
doSomeOtherWork(data);
}
})
});
});
し、再び「/ APIを/チェック状態」を、あなたは同じ「someDataObject」モデルを使用しますステータスを確認する:
var someDataObject = require("someDataObject");
var router = new express.Router();
router.get("/", checkStatus);
function checkStatus(req, res, next){
someDataObject.load(function(err, someData){
if (err) { return next(err); }
res.json({
complete: (someData.status === "complete"),
data: someData.data
});
});
}
これはうまくいけば正しいパスを取得します。私が残した細部はたくさんありますが、欠けている部分を埋めることができればうれしいです。
...
P.S:私は私のRabbitMQ 4 Devsトレーニングコースでは、タイマーのステータスの更新をチェックするブラウザを除いて、このすべてをカバーしています。これは、RabbitMQとNode.jsを起動して実行するための完全なパッケージです
これは状態の更新が必要な長期実行プロセスですか?または、これは、バックエンドからの非常に迅速な応答です。元のHTTP要求では、そのバックエンドサービスからの応答を取得する必要がありますか? –
私はそう思う状況の更新。場合によってはバックエンドは30秒+になります。 – user3320795
ええ、1秒以上の間、状態の更新が必要です。私はまもなく答えを発表します。 –