-
Notifications
You must be signed in to change notification settings - Fork 535
Question: Channels (api/channels.md) - Go to a channel on request #950
Comments
The trick with channels is that they should be represented by data that has been saved to the database because channels itself are not persistent and only local to the Feathers server. I think what you are looking for is similar to keeping the users rooms updated when they join/leave one, which could look like this: // Get a user to leave all channels
const leaveChannels = user => {
app.channel(app.channels).leave(connection =>
connection.user._id === user._id
);
};
// Update channels for updated user information
const updateUserChannels = function(user) {
// Find all connections for this user
const { connections } = app.channel(app.channels).filter(connection =>
connection.user._id === user._id
);
// Leave all channels
leaveChannels(user);
// Re-join all channels with the updated user information
connections.forEach(connection => {
app.channel('authenticated').join(connection);
// Assuming that the chat room/user assignment is stored
// on an array of the user
user.rooms.forEach(room =>
app.channel(`rooms/${roomId}`).join(connection)
)
});
}
app.service('users').on('updated', updateUser);
app.service('users').on('patched', updateUser);
app.service('users').on('removed', leaveChannels); |
So if you have 100k connections and one person joins a new channel, does feathers run this function for every single user? |
It will only run once whenever a user is updated, patched or removed. The old (v2) filter functions ran for every connection which was the big reason why we moved to the channel system (which is a lot faster and more secure). |
If anybody want a sample code: /* eslint-disable no-unused-vars */
const each = require('lodash.foreach');
class Service {
constructor (options) {
this.options = options || {};
}
setup(app) {
this.app = app;
}
async create (data, params) {
if (Array.isArray(data)) {
return await Promise.all(data.map(current => this.create(current)));
}
const channel = `${data.type}/${data.identifier}`;
const action = data.action;
if(action === "join"){
const { connections } = this.app.channel(this.app.channels).filter(connection => {
return connection.connection_id === params.connection_id;
});
console.log('join', params.connection_id, channel);
each(connections, connection => {
this.app.channel(channel).join(connection);
})
}else if(action === "leave"){
console.log('leave', params.connection_id, channel);
this.app.channel(channel).leave(connection => {
return connection.connection_id === params.connection_id;
});
}
// this.app.channel()[data.action]();
return data;
}
}
module.exports = function (options) {
return new Service(options);
};
module.exports.Service = Service; And in app.js; app.configure(socketio((io)=>{
io.use(function(socket, next) {
socket.feathers.connection_id = socket.id;
next();
});
})) Because my probleme is solved, I close the issue |
Thank you for your sample code |
@Buom01 Thanks for the code, been tearing my hair out for hours trying to work out a way to connect to rooms like this. |
Hi,
By using channels, I don't find out a working solution to add an user dynamically to a channel (by a call from the client)
For exemple, I've tried without success this code:
But after being correctly added to the connections list of the channel by calling the custom service, I don't get update from the publications
I have verified that the channel's name of publications and channel's name dynamically subscribed by the call are same, but nothing happed when the user got a mutation.
However it works with the channel
authenticated
.I think that the
connection
is not exactly the same asparams
argument, and it's probably the probleme.So, how to add a connection to a channel when the client request it ?
The text was updated successfully, but these errors were encountered: