Lately I've been working on a realtime web app built using React. I want to display which users are online currently. I've thought of many different ways to implement it, and chose the following implementation.
In my Laravel login controller, after the user has successfully logged in I've stored the user email as the key and user id as a value in a Redis Hash Structure.
In the get users controller, I am checking for each user if their email is present as a key in the Redis hash, shown as below
$users = User::all();
$users->map(function($user){
$user->setAttribute('online', 0);
if(Redis::hget('ActiveUsers',$user->email)) {
$user->setAttribute('online', 1);
}
});
return $users;
And as for the realtime displaying of the status I am using SocketIO and Redis pub/sub feature
redis.on('message', (channel, message) => {
io.emit('someone-logged-in', msg.data.id);
});
io.on('connection', (socket) => {
redis.subscribe('logged-in');
socket.on('loggedOut', data => {
ActiveUsersRedis.hdel("ActiveUsers", data.email);
io.emit('someone-logged-out', data.id);
});
In my React Application I'm handling the event as follows
this.state.socket.on('someone-logged-out',data => {
let i = this.state.activeUsersId.indexOf(parseInt(data, 10));
if(i !== -1)
{
this.state.activeUsersId.splice(i, 1);
this.setState({activeUsersId: this.state.activeUsersId});
}
});
this.state.socket.on('someone-logged-in',data => {
let e = true;
if(this.props.users.data)
e = this.props.users.data.some(user => user.id === data);
if(e) this.setState({activeUsersId: [...this.state.activeUsersId,data]});
});
I don't know if it is the best way or an optimal solution or if it's scalable upto 100k users. So, does anyone has a better approach or any suggestions on how can I improve this implementation?
via Chebli Mohamed
Aucun commentaire:
Enregistrer un commentaire