使用Sockets.io将流数据的子集发送到节点客户端

时间:2013-09-08 10:04:09

标签: javascript node.js sockets twitter

我有一个节点服务器,它使用Sockets.io和ntwitter在客户端连接时向客户端发送流式推文。目前,所有推文(来自不同用户)都被发送到每个客户端。但每个客户端只需要一定的推文子集,我希望服务器只发送该子集(或类别)。

认为让每个类别在套接字中都像一个房间一样可行,但我无法弄清楚如何调整我的代码来使用它们。或者,鉴于客户之间没有沟通,也许这不是最佳解决方案?

相关的,简化的当前代码......

客户端:

var socket = io.connect(window.location.hostname);

socket.on('messages', function(messages_packet) {
    $.each(messages_packet, function(idx, tweet) {
        if (tweet_is_in_this_clients_category(tweet)) {
            display_messages(messages_packet);
        };
    }
});

服务器:

// [A function which, on start-up, fetches existing tweets and caches them.]

// Send cached messages when a client connects.
sockets.sockets.on('connection', function(socket) {
    socket.emit('messages', cached_messages);
});

// Fetch tweets from the stream, and send new ones to clients.
twitter.stream('statuses/filter', {follow: [12345, 345678, etc]}, function(stream) {
    stream.on('data', function(tweet) {
        add_tweet_to_cache(tweet);
        sockets.sockets.emit('messages', [tweet]);
    }
});

因此,sockets.emit()部分目前正在向所有客户发送每条推文。然后客户决定是否显示该推文,如果它在客户的类别中。如果服务器仅向正确类别的客户端发送推文,那么效率显然会更高。鉴于服务器已经知道哪些推文属于哪些类别,我如何只将它们发送到这些类别而不是每个客户端?

1 个答案:

答案 0 :(得分:0)

经过一些试验和错误,我似乎有了它的工作。不知道这是不是最好或最正确的方法,但是...上面的代码已经调整过,所以它现在就像下面所示。客户端代码有一个附加内容,服务器代码有两个。

客户端:

var socket = io.connect(window.location.hostname);
// NEW CLIENT PART:
socket.on('connect', function(){
    // room_name was created based on the URL this page was requested at:
    socket.emit('subscribe', room_name);
};

socket.on('messages', function(messages_packet) {
    $.each(messages_packet, function(idx, tweet) {
        if (tweet_is_in_this_clients_category(tweet)) {
            display_messages(messages_packet);
        };
    }
});

服务器:

// [A function which, on start-up, fetches existing tweets and caches them.]

// Send cached messages when a client connects.
sockets.sockets.on('connection', function(socket) {
    // NEW SERVER PART 1:
    socket.on('subscribe', function(room_name) {
        socket.join(room_name);
        socket.emit('messages', cached_messages_for_this_room);
    });
});

// Fetch tweets from the stream, and send new ones to clients.
twitter.stream('statuses/filter', {follow: [12345, 345678, etc]}, function(stream) {
    stream.on('data', function(tweet) {
        add_tweet_to_cache(tweet);
        // NEW SERVER PART 2:
        // Gets the array of room_names this twitter account is associated with:
        var rooms = get_rooms_for_twitter_account(tweet.user.screen_name);
        rooms.forEach(
            function(room_name) {
                sockets.sockets.in(room_name).emit('messages', [tweet]);
            };
        );
    };
});

因此,当客户端连接时,它会发送一个“订阅”消息,以及它想要加入的房间的名称。

当服务器收到'subscribe'事件时,它只发送与该房间相关的现有推文(获取该推文列表的逻辑在其他地方完成;与此特定问题无关)。

每当服务器接收到新的推文时,它会找到与此推文相关联的房间,然后向每个客户发送推文。

这似乎有用......指出任何没有意义的事情,或者可以做得更好!