2

我有一个 RubyOnRails 应用程序,它使用 Node.js/Socket.io 服务器向所有连接的客户端推送交易信息。每当执行交易时,客户端屏幕都会使用最后一次交易的信息进行更新。

随着交易频率的增加,每秒更新一次甚至更频繁会变得相当烦人。我正在寻找一种方法来例如将更新推送给客户端。每 5 秒一次,即如果没有交易发生,则不会推送任何内容。

到目前为止我所拥有的是:我通过以下方式将交易信息从 Rails 应用程序推送到 Redis:

REDIS.publish('tradeupdate', ..... )

节点服务器执行以下操作:

cli_sub.subscribe("tradeupdate");
cli_sub.on("message",function(channel,message) {
    io.sockets.emit('ablv', message);
});

然后客户做

socket.on('ablv', function (data) {
    obj = JSON.parse(data);
    .....
});

目的是在给定时间段(例如 5 秒)内仅将最后一条消息从 Rails 发送到 Node 或从 Node 发送到客户端。

4

2 回答 2

2

是什么阻止您缓冲消息并使用简单的计时器每五秒执行一次发射?

var last_message = null;

cli_sub.subscribe("tradeupdate");
cli_sub.on("message",function(channel,message) {
    last_message = message;
});

setInterval(function() {
    io.sockets.emit('ablv', last_message);
}, 5000);
于 2013-08-14T10:30:27.157 回答
1

看起来你在这里需要的是一个限制你的函数调用的助手。例如:

var makeThrottler = function() {
    var toRun = null, timeout = null;

    function doRun() {
        if (!toRun) {
            // nothing to run; we set timeout to null so that the
            // next function to execute knows to run immediately
            timeout = null;
            return;
        }

        // set a timeout of 5s before
        timeout = setTimeout(function() {
            doRun();
        }, 5000);

        // we need to do this temp thing to protect against
        // calling executeThrottled again within toRun
        var temp = toRun;
        toRun = null;
        temp();
    }

    function executeThrottled(fn) {
        // this is the function we want to execute next; it
        // overwrites any function we've stored earlier
        toRun = fn;

        // if we already ran within the last 5 seconds, don't do
        // anything now (our function will be called later)
        if (timeout)
            return;

        // execute the function right away
        doRun();
    }

    return executeThrottled;
}

这是一个如何使用它的示例:

var throttled = makeThrottler(), x = 0;
function increment() {
    throttled(function() {
        console.log(x);
    });
    x++;
    setTimeout(increment, 1000);
}
increment();

增量函数x每秒增加一。日志记录受到限制,因此您将看到的输出是 0、5、10 等。(它们可能偶尔会因计时不准确而减少 1。)

您的原始代码将变为:

cli_sub.subscribe("tradeupdate");
cli_sub.on("message",function(channel,message) {
    throttled(function() {
        io.sockets.emit('ablv', message);
    });
});
于 2013-08-14T09:26:40.153 回答