Do not store room partticipants in the DB

Just in memory, it's not something we must store long term, was just needed to pass data between VROOM and SignalMaster
master
Daniel Berteaud 10 years ago
parent fd4d464a51
commit 1acb0795fb
  1. 206
      vroom.pl

@ -193,6 +193,11 @@ helper logout => sub {
if ($ec && $self->session($room) && $self->session($room)->{etherpadSessionId}){ if ($ec && $self->session($room) && $self->session($room)->{etherpadSessionId}){
$ec->delete_session($self->session($room)->{etherpadSessionId}); $ec->delete_session($self->session($room)->{etherpadSessionId});
} }
if ($self->session('peer_id') &&
$peers->{$self->session('peer_id')} &&
$peers->{$self->session('peer_id')}->{socket}){
$peers->{$self->session('peer_id')}->{socket}->finish;
}
$self->session( expires => 1 ); $self->session( expires => 1 );
$self->app->log->info($self->session('name') . " logged out"); $self->app->log->info($self->session('name') . " logged out");
return 1; return 1;
@ -316,104 +321,17 @@ helper modify_room => sub {
return 1; return 1;
}; };
# Add a participant in the database. Used by the signaling server to check
# if user is allowed
helper add_participant_to_room => sub {
my $self = shift;
my ($name,$participant) = @_;
my $room = $self->get_room_by_name($name);
if (!$room){
return 0;
}
my $sth = eval {
$self->db->prepare('INSERT INTO `room_participants`
(`room_id`,`participant`,`last_activity`)
VALUES (?,?,CONVERT_TZ(NOW(), @@session.time_zone, \'+00:00\'))
ON DUPLICATE KEY UPDATE `last_activity`=CONVERT_TZ(NOW(), @@session.time_zone, \'+00:00\')');
};
$sth->execute(
$room->{id},
$participant
);
$self->app->log->info($self->session('name') . " joined the room $name");
return 1;
};
# Remove participant from the DB
# Takes two args: room name and user name
helper remove_participant_from_room => sub {
my $self = shift;
my ($name,$participant) = @_;
my $room = $self->get_room_by_name($name);
if (!$room){
return 0;
}
my $sth = eval {
$self->db->prepare('DELETE FROM `room_participants`
WHERE `id`=?
AND `participant`=?');
};
$sth->execute(
$room->{id},
$participant
);
$self->app->log->info($self->session('name') . " leaved the room $name");
return 0;
};
# Get a list of participants of a room
helper get_participants_list => sub {
my $self = shift;
my ($name) = @_;
my $room = $self->get_room_by_name($name);
if (!$room){
return 0;
}
my $sth = eval {
$self->db->prepare('SELECT `participant`,`room_id`
FROM `room_participants`
WHERE `room_id`=?');
};
$sth->execute($room->{id});
return $sth->fetchall_hashref('room_id');
};
# Set the role of a peer # Set the role of a peer
helper set_peer_role => sub { helper set_peer_role => sub {
my $self = shift; my $self = shift;
my ($data) = @_; my ($data) = @_;
# Check if this ID isn't the one from another peer first # Check the peer exists and is already in the room
my $sth = eval { if (!$data->{peer_id} ||
$self->db->prepare('SELECT COUNT(`p`.`id`) !$peers->{$data->{peer_id}}){
FROM `room_participants` `p`
LEFT JOIN `rooms` `r` ON `p`.`room_id`=`r`.`id`
WHERE `p`.`peer_id`=?
AND `p`.`participant`!=?
AND `r`.`name`=?');
};
$sth->execute($data->{peer_id},$data->{name},$data->{room});
my $num;
$sth->bind_columns(\$num);
$sth->fetch;
if ($num > 0){
return 0; return 0;
} }
$sth = eval { $peers->{$data->{peer_id}}->{role} = $data->{role};
$self->db->prepare('UPDATE `room_participants` `p` $self->app->log->info("Peer " . $data->{peer_id} . " has now the " .
LEFT JOIN `rooms` `r` ON `p`.`room_id`=`r`.`id`
SET `p`.`peer_id`=?,
`p`.`role`=?
WHERE `p`.`participant`=?
AND `r`.`name`=?');
};
$sth->execute(
$data->{peer_id},
$data->{role},
$data->{name},
$data->{room}
);
$self->app->log->info("User " . $data->{name} . " (peer id " .
$data->{peer_id} . ") has now the " .
$data->{role} . " role in room " . $data->{room}); $data->{role} . " role in room " . $data->{room});
return 1; return 1;
}; };
@ -422,75 +340,18 @@ helper set_peer_role => sub {
helper get_peer_role => sub { helper get_peer_role => sub {
my $self = shift; my $self = shift;
my ($data) = @_; my ($data) = @_;
my $sth = eval { return $peers->{$data->{peer_id}}->{role};
$self->db->prepare('SELECT `p`.`role`
FROM `room_participants` `p`
LEFT JOIN `rooms` `r` ON `p`.`room_id`=`r`.`id`
WHERE `p`.`peer_id`=?
AND `r`.`name`=?
LIMIT 1');
};
$sth->execute(
$data->{peer_id},
$data->{room}
);
my $role;
$sth->bind_columns(\$role);
$sth->fetch;
return $role;
}; };
# Promote a peer to owner # Promote a peer to owner
helper promote_peer => sub { helper promote_peer => sub {
my $self = shift; my $self = shift;
my ($data) = @_; my ($data) = @_;
my $sth = eval { return $self->set_peer_role({
$self->db->prepare('UPDATE `room_participants` `p` peer_id => $data->{peer_id},
LEFT JOIN `rooms` `r` ON `p`.`room_id`=`r`.`id` room => $data->{room},
SET `p`.`role`=\'owner\' role => 'owner'
WHERE `p`.`peer_id`=? });
AND `r`.`name`=?');
};
$sth->execute(
$data->{peer_id},
$data->{room}
);
return 1;
};
# Check if a participant has joined a room
# Takes a hashref room => room name and name => session name
helper has_joined => sub {
my $self = shift;
my ($data) = @_;
my $sth = eval {
$self->db->prepare('SELECT COUNT(`r`.`id`)
FROM `rooms` `r`
LEFT JOIN `room_participants` `p` ON `r`.`id`=`p`.`room_id`
WHERE `r`.`name`=?
AND `p`.`participant`=?');
};
$sth->execute(
$data->{room},
$data->{name}
);
my $num;
$sth->bind_columns(\$num);
$sth->fetch;
return ($num == 1) ? 1 : 0 ;
};
# Purge disconnected participants from the DB
helper purge_participants => sub {
my $self = shift;
$self->app->log->debug('Removing inactive participants from the database');
my $sth = eval {
$self->db->prepare('DELETE FROM `room_participants`
WHERE `last_activity` < DATE_SUB(CONVERT_TZ(NOW(), @@session.time_zone, \'+00:00\'), INTERVAL 10 MINUTE)
OR `last_activity` IS NULL');
};
$sth->execute;
return 1;
}; };
# Purge api keys # Purge api keys
@ -1174,7 +1035,7 @@ websocket '/socket.io/:ver/websocket/:id' => sub {
my ($self, $code, $reason) = @_; my ($self, $code, $reason) = @_;
$self->app->log->debug("Client id " . $id . " closed websocket connection"); $self->app->log->debug("Client id " . $id . " closed websocket connection");
foreach my $peer (keys %$peers){ foreach my $peer (keys %$peers){
next if ($peer eq $id); next if $peer eq $id;
next if $peers->{$peer}->{room} ne $peers->{$id}->{room}; next if $peers->{$peer}->{room} ne $peers->{$id}->{room};
$self->app->log->debug("Notifying $peer that $id leaved"); $self->app->log->debug("Notifying $peer that $id leaved");
$peers->{$peer}->{socket}->send( $peers->{$peer}->{socket}->send(
@ -1191,9 +1052,8 @@ websocket '/socket.io/:ver/websocket/:id' => sub {
} }
) )
); );
}
# Remove this peer from our global hash
delete $peers->{$id}; delete $peers->{$id};
}
}); });
# This is just the end of the initial handshake, we indicate the client we're ready # This is just the end of the initial handshake, we indicate the client we're ready
@ -1206,9 +1066,14 @@ Mojo::IOLoop->recurring( 3 => sub {
foreach my $peer ( keys %$peers ) { foreach my $peer ( keys %$peers ) {
# If we had no reply from this peer in the last 15 sec # If we had no reply from this peer in the last 15 sec
# (5 heartbeat without response), we consider it dead and remove it # (5 heartbeat without response), we consider it dead and remove it
if ($peers->{$peer}->{last} < time - 15){ if (!$peers->{$peer}->{socket}){
app->log->debug("Garbage found in peers (peer $peer)\n" . Dumper($peers->{$peer}));
delete $peers->{$peer};
}
elsif ($peers->{$peer}->{last} < time - 15){
app->log->debug("Peer $peer didn't reply in 15 sec, disconnecting"); app->log->debug("Peer $peer didn't reply in 15 sec, disconnecting");
$peers->{$peer}->{socket}->finish; $peers->{$peer}->{socket}->finish;
delete $peers->{$peer};
} }
else { else {
$peers->{$peer}->{socket}->send(Protocol::SocketIO::Message->new( type => 'heartbeat' )); $peers->{$peer}->{socket}->send(Protocol::SocketIO::Message->new( type => 'heartbeat' ));
@ -1258,10 +1123,11 @@ post '/feedback' => sub {
get '/goodbye/(:room)' => sub { get '/goodbye/(:room)' => sub {
my $self = shift; my $self = shift;
my $room = $self->stash('room'); my $room = $self->stash('room');
if ($self->get_room_by_name($room) && $self->session('name')){ if (!$self->get_room_by_name($room)){
$self->remove_participant_from_room( return $self->render('error',
$room, err => 'ERROR_ROOM_s_DOESNT_EXIST',
$self->session('name') msg => sprintf ($self->l("ERROR_ROOM_s_DOESNT_EXIST"), $room),
room => $room
); );
} }
$self->logout($room); $self->logout($room);
@ -1279,10 +1145,6 @@ get '/kicked/(:room)' => sub {
room => $room room => $room
); );
} }
$self->remove_participant_from_room(
$room,
$self->session('name')
);
$self->logout($room); $self->logout($room);
} => 'kicked'; } => 'kicked';
@ -1579,7 +1441,6 @@ any '/api' => sub {
if ((int (rand 100)) <= 10){ if ((int (rand 100)) <= 10){
$self->purge_rooms; $self->purge_rooms;
$self->purge_invitations; $self->purge_invitations;
$self->purge_participants;
} }
# Check if we got any invitation response to process # Check if we got any invitation response to process
my $invitations = $self->get_invitation_list($self->session('name')); my $invitations = $self->get_invitation_list($self->session('name'));
@ -1865,7 +1726,6 @@ any '/api' => sub {
} }
my $res = $self->set_peer_role({ my $res = $self->set_peer_role({
room => $room->{name}, room => $room->{name},
name => $self->session('name'),
peer_id => $peer_id, peer_id => $peer_id,
role => $self->session($room->{name})->{role} role => $self->session($room->{name})->{role}
}); });
@ -2117,14 +1977,6 @@ get '/:room' => sub {
} }
$self->create_etherpad_session($room); $self->create_etherpad_session($room);
} }
# Add this user to the participants table
if (!$self->add_participant_to_room($room, $self->session('name'))){
return $self->render('error',
msg => $self->l('ERROR_OCCURRED'),
err => 'ERROR_OCCURRED',
room => $room
);
}
# Now display the room page # Now display the room page
return $self->render('join', return $self->render('join',
moh => $self->choose_moh(), moh => $self->choose_moh(),

Loading…
Cancel
Save