我正在编写REST api,该api必须提供用户之间的实时通信。可以说我有db.orders
集合。而且我有api GET /order/{id}
。此api应该等待order
文档中的某些更改。例如,仅当order.status
为ready
时,它才应返回一些数据。我知道如何进行长轮询,但是我不知道如何检查数据是否在db中显示/更改。如果只有一个应用程序实例,这将很容易-然后我可以在内存中执行此操作,如下所示:
var queue = []
// GET /order/{id}
function(req,res,next) {
var data = getDataFromDb();
if(data && data.status == 'ready') {
res.send(data);
return;
}
queue.push({id: req.params.id, req: req, res: res, next: next});
}
// POST /order/{id}
function(req,res,next) {
req.params.data.status = 'ready'
saveToDb(req.params.data);
var item = findInQueue(queue,req.params.id);
if(item) item.res.send(req.params.data);
}
第一个处理程序等待数据的状态为
ready
,第二个处理程序将数据的状态设置为ready
。它只是一个伪代码,很多东西都丢失了(例如超时)。问题是当我想使用此类应用程序的许多实例时-我需要某种消息传递机制,该机制将允许在各种实例之间进行实时通信。
我阅读了有关REDIS PUB / SUB的信息,但不确定是否可以这种方式使用它...
我现在正在使用node.js + restify + mongoDB。
最佳答案
您正在寻找oplog。这是一个特殊的封顶集合,用于存储数据库上的所有操作。要在单个服务器上启用它们,您可以执行。
mongod --dbpath=./data --oplogSize=100 --replSet test
然后使用控制台连接到服务器并编写
rs.initiate()
使用控制台并执行
use local
show collections
注意集合oplog.rs。它包含已应用于服务器的所有操作。如果您使用的是node.js,则可以按以下方式收听更改
var local = db.db("local");
var steam = local.collection("oplog.rs").find({}, {tailable:true, awaitdata:true}).stream();
stream.on('data', function(doc) {
});
对于mongodb上的每个操作,您都会收到一个文档,您可以在其中确定是否对更改状态感兴趣。