Skip to content
This repository has been archived by the owner on Aug 29, 2018. It is now read-only.

Clean way to subscribe to a filtered set of events #32

Closed
TylerU opened this issue Jul 5, 2016 · 3 comments
Closed

Clean way to subscribe to a filtered set of events #32

TylerU opened this issue Jul 5, 2016 · 3 comments

Comments

@TylerU
Copy link

TylerU commented Jul 5, 2016

Say I wanted to implement a real-time chat app with multiple chat rooms that can be created and deleted dynamically. The client who is in chat room "football buddies" wants to subscribe to the messages service but is only interested in messages to that room. If I understand feathers correctly, feathers will send all events on the message service, which might be a lot if there are a lot of small chat rooms.

Perhaps the socket.io concept of namespaces and rooms is useful here, but I'm not sure of the best way to set it up within the feathers ecosystem.

I think feathers-reactive would effectively accomplish this from the point of view of my app, but the client side is still dealing with all the useless websocket traffic, which is undesirable.

I also see that event filtering might accomplish this, but it seems like I'd need to add some server-side functionality for tracking which users are currently connected to a given chat room, which seems less clean than simply being able to subscribe to a subset of the events on a service.

Any help is appreciated.

Thanks.

@daffl
Copy link
Member

daffl commented Jul 6, 2016

This is exactly what event filters are for. Primus and other (potential) real-time providers don't have a concept of rooms and everything that rooms can do - and more complex functionality (which you almost always need) - can also be done through event filters. There are two options:

  1. Add the rooms a user is in to the user object and compare the messages room to the rooms the user is subscribed to. This is usually the best way since you can e.g. show offline users that joined a room (which isn't easily possible with Socket.io rooms)
  2. Add a custom Socket.io join event and add the connected room directly to the connection and then filter by the rooms on that connection:
app.use(socketio(function(io) {
  io.on('connection', function(socket) {
    socket.on('join', function(roomId) {
      socket.feathers.rooms.push(roomId);
    });
  });
}));

app.service('messages').filter(function(data, connection) {
  return connection.rooms.indexOf(data.room) !== -1;
});

@ekryski
Copy link
Member

ekryski commented Jul 7, 2016

Yup. That will do it! I'm going to close but this has come up a few times I'm wondering if we should put it in as an example in the docs under "rooms" or "channels". I dunno... maybe people just aren't seeing the that part of the docs too....

@daffl
Copy link
Member

daffl commented Jul 16, 2016

@daffl daffl reopened this Jul 16, 2016
@daffl daffl closed this as completed Jul 16, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants