简体   繁体   English

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

[英]Sending subsets of streaming data to Node clients using Sockets.io

I have a Node server which sends streaming tweets to clients as they connect, using Sockets.io and ntwitter. 我有一个节点服务器,它使用Sockets.io和ntwitter在客户端连接时向客户端发送流式推文。 At the moment all the tweets (from different users) get sent to every client. 目前,所有(来自不同用户)的推文都发送给每个客户端。 But each client only requires a certain subset of tweets, and I'd like to the server to only send that subset (or category). 但是每个客户端仅需要某些特定的tweet子集,我希望服务器仅发送该子集(或类别)。

I think that having each category being like a room, in Sockets, would work, but I can't quite work out how to adapt my code to use them. 认为在Sockets中让每个类别都像一个房间一样有效,但是我还不太清楚如何使我的代码适应使用它们。 Or, given that there's no communication between clients, maybe that's not the best solution? 或者,鉴于客户端之间没有通信,也许这不是最佳解决方案?

The relevant, simplified, bits of current code... 当前代码的相关的,简化的位...

Client: 客户:

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);
        };
    }
});

Server: 服务器:

// [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]);
    }
});

So, the sockets.emit() part is currently sending every tweet to all the clients. 因此, sockets.emit()部分当前正在将每条推文发送给所有客户端。 And then the client decides whether to show that tweet, if it's in the client's category. 然后,客户决定是否显示该tweet(如果属于该客户的类别)。 It would obviously be more efficient if the server only sent tweets to the clients in the correct category. 如果服务器仅向正确类别的客户端发送推文,显然会更有效率。 Given the server already knows which tweets are in which categories, how do I only emit them to those categories, rather than every client? 给定服务器已经知道哪些推文属于哪些类别,我如何只将它们发送给那些类别,而不是每个客户端?

After some trial and error I seem to have it working. 经过一番反复尝试后,我似乎可以正常使用了。 No idea if this is the best or correct way, but... the above code has been tweaked so it's now something like that shown below. 不知道这是最好还是正确的方法,但是...上面的代码已经过调整,因此现在类似于下面所示。 There's one addition to the client code, and two to the server code. 客户端代码有一个附加内容,服务器代码有两个附加内容。

Client: 客户:

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);
        };
    }
});

Server: 服务器:

// [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]);
            };
        );
    };
});

So, when a client connects it sends a 'subscribe' message, and the name of the room it wants to join. 因此,当客户端连接时,它将发送“订阅”消息以及要加入的会议室的名称。

When the server receives a 'subscribe' event it sends only the existing tweets associated with that room (the logic for getting that list of tweets is done elsewhere; not relevant to this particular issue). 当服务器接收到“订阅”事件时,它仅发送与该会议室关联的现有推文(获取该推文列表的逻辑在其他地方完成;与该特定问题无关)。

And whenever a new tweet is picked up by the server, it finds the room(s) this tweet is associated with, and then emits the tweet to every client in each of them. 并且,每当服务器接收到一条新的tweet时,它就会找到与该tweet关联的房间,然后将该tweet发出给每个客户端。

This seems to work... do point out anything that makes no sense, or could be done much better! 这似乎可行……确实指出了没有任何意义或可以做得更好的任何事情!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM