From 4243adb5f1f9a379b73730783b16e5a7e17c0445 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Sep 2017 13:20:51 +0200 Subject: [PATCH 01/21] Add events for delete/rename/change of a rooom Signed-off-by: Joas Schilling --- lib/Room.php | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/lib/Room.php b/lib/Room.php index dee33590c..1d6bdb2c3 100644 --- a/lib/Room.php +++ b/lib/Room.php @@ -196,6 +196,8 @@ class Room { } public function deleteRoom() { + $this->dispatcher->dispatch(self::class . '::preDeleteRoom', new GenericEvent($this)); + $query = $this->db->getQueryBuilder(); // Delete all participants @@ -207,6 +209,8 @@ class Room { $query->delete('spreedme_rooms') ->where($query->expr()->eq('id', $query->createNamedParameter($this->getId(), IQueryBuilder::PARAM_INT))); $query->execute(); + + $this->dispatcher->dispatch(self::class . '::postDeleteRoom', new GenericEvent($this)); } /** @@ -222,6 +226,13 @@ class Room { return false; } + $oldName = $this->getName(); + + $this->dispatcher->dispatch(self::class . '::preSetName', new GenericEvent($this, [ + 'newName' => $newName, + 'oldName' => $oldName, + ])); + $query = $this->db->getQueryBuilder(); $query->update('spreedme_rooms') ->set('name', $query->createNamedParameter($newName)) @@ -229,6 +240,11 @@ class Room { $query->execute(); $this->name = $newName; + $this->dispatcher->dispatch(self::class . '::postSetName', new GenericEvent($this, [ + 'newName' => $newName, + 'oldName' => $oldName, + ])); + return true; } @@ -268,6 +284,11 @@ class Room { $oldType = $this->getType(); + $this->dispatcher->dispatch(self::class . '::preChangeType', new GenericEvent($this, [ + 'newType' => $newType, + 'oldType' => $oldType, + ])); + $query = $this->db->getQueryBuilder(); $query->update('spreedme_rooms') ->set('type', $query->createNamedParameter($newType, IQueryBuilder::PARAM_INT)) @@ -285,6 +306,11 @@ class Room { $query->execute(); } + $this->dispatcher->dispatch(self::class . '::postChangeType', new GenericEvent($this, [ + 'newType' => $newType, + 'oldType' => $oldType, + ])); + return true; } @@ -332,22 +358,38 @@ class Room { * @param IUser $user */ public function removeUser(IUser $user) { + $this->dispatcher->dispatch(self::class . '::preRemoveUser', new GenericEvent($this, [ + 'user' => $user, + ])); + $query = $this->db->getQueryBuilder(); $query->delete('spreedme_room_participants') ->where($query->expr()->eq('roomId', $query->createNamedParameter($this->getId(), IQueryBuilder::PARAM_INT))) ->andWhere($query->expr()->eq('userId', $query->createNamedParameter($user->getUID()))); $query->execute(); + + $this->dispatcher->dispatch(self::class . '::postRemoveUser', new GenericEvent($this, [ + 'user' => $user, + ])); } /** * @param Participant $participant */ public function removeParticipantBySession(Participant $participant) { + $this->dispatcher->dispatch(self::class . '::preRemoveBySession', new GenericEvent($this, [ + 'participant' => $participant, + ])); + $query = $this->db->getQueryBuilder(); $query->delete('spreedme_room_participants') ->where($query->expr()->eq('roomId', $query->createNamedParameter($this->getId(), IQueryBuilder::PARAM_INT))) ->andWhere($query->expr()->eq('sessionId', $query->createNamedParameter($participant->getSessionId()))); $query->execute(); + + $this->dispatcher->dispatch(self::class . '::postRemoveBySession', new GenericEvent($this, [ + 'participant' => $participant, + ])); } /** From 5ab50955059159c5da606bffca28df5b99b465ee Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Sep 2017 13:42:52 +0200 Subject: [PATCH 02/21] Add a (collective) event when adding users to a call Signed-off-by: Joas Schilling --- lib/Controller/RoomController.php | 40 +++++++++++++++++++++++++------ lib/Room.php | 40 +++++++++++++++++++------------ 2 files changed, 58 insertions(+), 22 deletions(-) diff --git a/lib/Controller/RoomController.php b/lib/Controller/RoomController.php index dec0ae5d0..2065540d5 100644 --- a/lib/Controller/RoomController.php +++ b/lib/Controller/RoomController.php @@ -340,9 +340,14 @@ class RoomController extends OCSController { return new DataResponse(['token' => $room->getToken()], Http::STATUS_OK); } catch (RoomNotFoundException $e) { $room = $this->manager->createOne2OneRoom(); - $room->addParticipant($currentUser->getUID(), Participant::OWNER); + $room->addUsers([ + 'userId' => $currentUser->getUID(), + 'participantType' => Participant::OWNER, + ], [ + 'userId' => $targetUser->getUID(), + 'participantType' => Participant::OWNER, + ]); - $room->addParticipant($targetUser->getUID(), Participant::OWNER); $this->createNotification($currentUser, $targetUser, $room); return new DataResponse(['token' => $room->getToken()], Http::STATUS_CREATED); @@ -371,19 +376,27 @@ class RoomController extends OCSController { // Create the room $room = $this->manager->createGroupRoom($targetGroup->getGID()); - $room->addParticipant($currentUser->getUID(), Participant::OWNER); + $room->addUsers([ + 'userId' => $currentUser->getUID(), + 'participantType' => Participant::OWNER, + ]); $usersInGroup = $targetGroup->getUsers(); + $participants = []; foreach ($usersInGroup as $user) { if ($currentUser->getUID() === $user->getUID()) { // Owner is already added. continue; } - $room->addUser($user); + $participants[] = [ + 'userId' => $user->getUID(), + ]; $this->createNotification($currentUser, $user, $room); } + call_user_func_array([$room, 'addUsers'], $participants); + return new DataResponse(['token' => $room->getToken()], Http::STATUS_CREATED); } @@ -393,9 +406,18 @@ class RoomController extends OCSController { * @return DataResponse */ protected function createPublicRoom() { + $currentUser = $this->userManager->get($this->userId); + + if (!$currentUser instanceof IUser) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + // Create the room $room = $this->manager->createPublicRoom(); - $room->addParticipant($this->userId, Participant::OWNER); + $room->addUsers([ + 'userId' => $currentUser->getUID(), + 'participantType' => Participant::OWNER, + ]); return new DataResponse(['token' => $room->getToken()], Http::STATUS_CREATED); } @@ -535,13 +557,17 @@ class RoomController extends OCSController { // In case a user is added to a one2one call, we change the call to a group call $room->changeType(Room::GROUP_CALL); - $room->addUser($newUser); + $room->addUsers([ + 'userId' => $newUser->getUID(), + ]); $this->createNotification($currentUser, $newUser, $room); return new DataResponse(['type' => $room->getType()]); } - $room->addUser($newUser); + $room->addUsers([ + 'userId' => $newUser->getUID(), + ]); $this->createNotification($currentUser, $newUser, $room); return new DataResponse([]); diff --git a/lib/Room.php b/lib/Room.php index 1d6bdb2c3..58ab6fff8 100644 --- a/lib/Room.php +++ b/lib/Room.php @@ -315,30 +315,36 @@ class Room { } /** - * @param IUser $user + * @param array[] ...$participants */ - public function addUser(IUser $user) { - $this->addParticipant($user->getUID(), Participant::USER); - } + public function addUsers(array ...$participants) { + $this->dispatcher->dispatch(self::class . '::preAddUsers', new GenericEvent($this, [ + 'users' => $participants, + ])); - /** - * @param string $participant - * @param int $participantType - * @param string $sessionId - */ - public function addParticipant($participant, $participantType, $sessionId = '0') { $query = $this->db->getQueryBuilder(); $query->insert('spreedme_room_participants') ->values( [ - 'userId' => $query->createNamedParameter($participant), + 'userId' => $query->createParameter('userId'), + 'sessionId' => $query->createParameter('sessionId'), + 'participantType' => $query->createParameter('participantType'), 'roomId' => $query->createNamedParameter($this->getId()), 'lastPing' => $query->createNamedParameter(0, IQueryBuilder::PARAM_INT), - 'sessionId' => $query->createNamedParameter($sessionId), - 'participantType' => $query->createNamedParameter($participantType, IQueryBuilder::PARAM_INT), ] ); - $query->execute(); + + foreach ($participants as $participant) { + $query->setParameter('userId', $participant['userId']) + ->setParameter('sessionId', isset($participant['sessionId']) ? $participant['sessionId'] : '0') + ->setParameter('participantType', isset($participant['participantType']) ? $participant['participantType'] : Participant::USER, IQueryBuilder::PARAM_INT); + + $query->execute(); + } + + $this->dispatcher->dispatch(self::class . '::postAddUsers', new GenericEvent($this, [ + 'users' => $participants, + ])); } /** @@ -417,7 +423,11 @@ class Room { } // User joining a public room, without being invited - $this->addParticipant($userId, Participant::USER_SELF_JOINED, $sessionId); + $this->addUsers([ + 'userId' => $userId, + 'participantType' => Participant::USER_SELF_JOINED, + 'sessionId' => $sessionId, + ]); } while (!$this->isSessionUnique($sessionId)) { From b9912941f0e2a6f37b23091ffb278cce50cfdd6a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Sep 2017 13:46:06 +0200 Subject: [PATCH 03/21] Make it clearer that this is the userId Signed-off-by: Joas Schilling --- lib/Room.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Room.php b/lib/Room.php index 58ab6fff8..51dcbf7d3 100644 --- a/lib/Room.php +++ b/lib/Room.php @@ -582,15 +582,15 @@ class Room { } /** - * @param string $participant + * @param string $userId * @param string $sessionId * @param int $timestamp */ - public function ping($participant, $sessionId, $timestamp) { + public function ping($userId, $sessionId, $timestamp) { $query = $this->db->getQueryBuilder(); $query->update('spreedme_room_participants') ->set('lastPing', $query->createNamedParameter($timestamp, IQueryBuilder::PARAM_INT)) - ->where($query->expr()->eq('userId', $query->createNamedParameter((string) $participant))) + ->where($query->expr()->eq('userId', $query->createNamedParameter((string) $userId))) ->andWhere($query->expr()->eq('sessionId', $query->createNamedParameter($sessionId))) ->andWhere($query->expr()->eq('roomId', $query->createNamedParameter($this->getId(), IQueryBuilder::PARAM_INT))); From 51a5f8618cbd52dc9c78278ab34a95ccda628bd4 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Sep 2017 13:46:41 +0200 Subject: [PATCH 04/21] Use self:: instead of Room:: Signed-off-by: Joas Schilling --- lib/Room.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Room.php b/lib/Room.php index 51dcbf7d3..0b89dee98 100644 --- a/lib/Room.php +++ b/lib/Room.php @@ -214,7 +214,7 @@ class Room { } /** - * @param string $newName Currently it is only allowed to rename: Room::GROUP_CALL, Room::PUBLIC_CALL + * @param string $newName Currently it is only allowed to rename: self::GROUP_CALL, self::PUBLIC_CALL * @return bool True when the change was valid, false otherwise */ public function setName($newName) { @@ -270,7 +270,7 @@ class Room { } /** - * @param int $newType Currently it is only allowed to change to: Room::GROUP_CALL, Room::PUBLIC_CALL + * @param int $newType Currently it is only allowed to change to: self::GROUP_CALL, self::PUBLIC_CALL * @return bool True when the change was valid, false otherwise */ public function changeType($newType) { @@ -278,7 +278,7 @@ class Room { return true; } - if (!in_array($newType, [Room::GROUP_CALL, Room::PUBLIC_CALL], true)) { + if (!in_array($newType, [self::GROUP_CALL, self::PUBLIC_CALL], true)) { return false; } @@ -297,7 +297,7 @@ class Room { $this->type = (int) $newType; - if ($oldType === Room::PUBLIC_CALL) { + if ($oldType === self::PUBLIC_CALL) { // Kick all guests and users that were not invited $query = $this->db->getQueryBuilder(); $query->delete('spreedme_room_participants') From 9a6c4410a133f331877f157bb292f8ebf2fb8de6 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Sep 2017 14:19:28 +0200 Subject: [PATCH 05/21] Add events when participants disconnect Signed-off-by: Joas Schilling --- lib/Controller/CallController.php | 29 ++++++++++++--------------- lib/Manager.php | 21 -------------------- lib/Room.php | 33 ++++++++++++++++++++++++------- 3 files changed, 39 insertions(+), 44 deletions(-) diff --git a/lib/Controller/CallController.php b/lib/Controller/CallController.php index 32d9d071e..4710b4f74 100644 --- a/lib/Controller/CallController.php +++ b/lib/Controller/CallController.php @@ -201,26 +201,23 @@ class CallController extends OCSController { * @return DataResponse */ public function leaveCall($token) { - if ($this->userId !== null) { - try { - $room = $this->manager->getRoomForParticipantByToken($token, $this->userId); + $sessionId = $this->session->get('spreed-session'); + $this->session->remove('spreed-session'); + + try { + $room = $this->manager->getRoomForParticipantByToken($token, $this->userId); + + if ($this->userId === null) { + $participant = $room->getParticipantBySession($sessionId); + $room->removeParticipantBySession($participant); + } else { $participant = $room->getParticipant($this->userId); - - if ($participant->getParticipantType() === Participant::USER_SELF_JOINED) { - $room->removeParticipantBySession($participant); - } - } catch (RoomNotFoundException $e) { - } catch (\RuntimeException $e) { + $room->disconnectUserFromAllRooms($participant->getUser()); } - - // As a pre-caution we simply disconnect the user from all rooms - $this->manager->disconnectUserFromAllRooms($this->userId); - } else { - $sessionId = $this->session->get('spreed-session'); - $this->manager->removeSessionFromAllRooms($sessionId); + } catch (RoomNotFoundException $e) { + } catch (ParticipantNotFoundException $e) { } - $this->session->remove('spreed-session'); return new DataResponse(); } diff --git a/lib/Manager.php b/lib/Manager.php index 9df4750e0..9dfe73272 100644 --- a/lib/Manager.php +++ b/lib/Manager.php @@ -394,27 +394,6 @@ class Manager { return $row['sessionId']; } - /** - * @param string $userId - */ - public function disconnectUserFromAllRooms($userId) { - $query = $this->db->getQueryBuilder(); - $query->update('spreedme_room_participants') - ->set('sessionId', $query->createNamedParameter('0')) - ->where($query->expr()->eq('userId', $query->createNamedParameter($userId))); - $query->execute(); - } - - /** - * @param string $sessionId - */ - public function removeSessionFromAllRooms($sessionId) { - $query = $this->db->getQueryBuilder(); - $query->delete('spreedme_room_participants') - ->where($query->expr()->eq('sessionId', $query->createNamedParameter($sessionId))); - $query->execute(); - } - /** * @param string $userId * @return string[] diff --git a/lib/Room.php b/lib/Room.php index 0b89dee98..1aefb45e3 100644 --- a/lib/Room.php +++ b/lib/Room.php @@ -407,6 +407,8 @@ class Room { public function enterRoomAsUser($userId, $password) { $this->dispatcher->dispatch(self::class . '::preUserEnterRoom', new GenericEvent($this)); + $this->disconnectUserFromAllRooms($userId); + $query = $this->db->getQueryBuilder(); $query->update('spreedme_room_participants') ->set('sessionId', $query->createParameter('sessionId')) @@ -436,18 +438,35 @@ class Room { $query->execute(); } - $query = $this->db->getQueryBuilder(); - $query->update('spreedme_room_participants') - ->set('sessionId', $query->createNamedParameter('0')) - ->where($query->expr()->neq('roomId', $query->createNamedParameter($this->getId(), IQueryBuilder::PARAM_INT))) - ->andWhere($query->expr()->eq('userId', $query->createNamedParameter($userId))); - $query->execute(); - $this->dispatcher->dispatch(self::class . '::postUserEnterRoom', new GenericEvent($this)); return $sessionId; } + /** + * @param string $userId + */ + public function disconnectUserFromAllRooms($userId) { + $this->dispatcher->dispatch(self::class . '::preUserDisconnectRoom', new GenericEvent($this)); + + // Reset sessions on all normal rooms + $query = $this->db->getQueryBuilder(); + $query->update('spreedme_room_participants') + ->set('sessionId', $query->createNamedParameter('0')) + ->where($query->expr()->eq('userId', $query->createNamedParameter($userId))) + ->andWhere($query->expr()->neq('participantType', $query->createNamedParameter(Participant::USER_SELF_JOINED, IQueryBuilder::PARAM_INT))); + $query->execute(); + + // And kill session on all self joined rooms + $query = $this->db->getQueryBuilder(); + $query->delete('spreedme_room_participants') + ->where($query->expr()->eq('userId', $query->createNamedParameter($userId))) + ->andWhere($query->expr()->eq('participantType', $query->createNamedParameter(Participant::USER_SELF_JOINED, IQueryBuilder::PARAM_INT))); + $query->execute(); + + $this->dispatcher->dispatch(self::class . '::postUserDisconnectRoom', new GenericEvent($this)); + } + /** * @param string $password * @return string From 8108d3587fbac0a898cd1ace6bf24606a391d005 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 18 Jul 2017 14:57:19 +0200 Subject: [PATCH 06/21] Use an OCS controller and long polling instead of event sources Signed-off-by: Joas Schilling --- appinfo/routes.php | 26 +++++--- lib/Controller/SignallingController.php | 89 ++++++++++++++----------- 2 files changed, 66 insertions(+), 49 deletions(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index e5076e0d0..9121be96e 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -28,16 +28,6 @@ return [ 'url' => '/', 'verb' => 'GET', ], - [ - 'name' => 'Signalling#signalling', - 'url' => '/signalling', - 'verb' => 'POST', - ], - [ - 'name' => 'Signalling#pullMessages', - 'url' => '/messages', - 'verb' => 'GET', - ], [ 'name' => 'AppSettings#setSpreedSettings', 'url' => '/settings/admin', @@ -45,6 +35,22 @@ return [ ], ], 'ocs' => [ + [ + 'name' => 'Signalling#signalling', + 'url' => '/api/{apiVersion}/signalling', + 'verb' => 'POST', + 'requirements' => [ + 'apiVersion' => 'v1', + ], + ], + [ + 'name' => 'Signalling#pullMessages', + 'url' => '/api/{apiVersion}/messages', + 'verb' => 'GET', + 'requirements' => [ + 'apiVersion' => 'v1', + ], + ], [ 'name' => 'Call#getPeersForCall', 'url' => '/api/{apiVersion}/call/{token}', diff --git a/lib/Controller/SignallingController.php b/lib/Controller/SignallingController.php index 22a33f31e..54ffd66c5 100644 --- a/lib/Controller/SignallingController.php +++ b/lib/Controller/SignallingController.php @@ -28,13 +28,13 @@ use OCA\Spreed\Exceptions\RoomNotFoundException; use OCA\Spreed\Manager; use OCA\Spreed\Room; use OCA\Spreed\Signalling\Messages; -use OCP\AppFramework\Controller; -use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\OCSController; use OCP\IDBConnection; use OCP\IRequest; use OCP\ISession; -class SignallingController extends Controller { +class SignallingController extends OCSController { /** @var Config */ private $config; /** @var ISession */ @@ -79,7 +79,7 @@ class SignallingController extends Controller { * @PublicPage * * @param string $messages - * @return JSONResponse + * @return DataResponse */ public function signalling($messages) { $response = []; @@ -128,35 +128,39 @@ class SignallingController extends Controller { } } - return new JSONResponse($response); + return new DataResponse($response); } /** * @PublicPage + * @return DataResponse */ public function pullMessages() { set_time_limit(0); - $eventSource = \OC::$server->createEventSource(); + $data = []; + $seconds = 30; - while(true) { + while ($seconds > 0) { + // Guest if ($this->userId === null) { $sessionId = $this->session->get('spreed-session'); - if (empty($sessionId)) { - // User is not active anywhere - $eventSource->send('usersInRoom', []); - $currentParticipant = false; + if ($sessionId === null) { + // User is not active anywhere; + $data[] = ['type' => 'usersInRoom', 'data' => []]; break; - } else { - $qb = $this->dbConnection->getQueryBuilder(); - $qb->select('*') - ->from('spreedme_room_participants') - ->where($qb->expr()->eq('sessionId', $qb->createNamedParameter($sessionId))) - ->andWhere($qb->expr()->eq('userId', $qb->createNamedParameter((string)$this->userId))); - $result = $qb->execute(); - $currentParticipant = $result->fetch(); - $result->closeCursor(); } + + $qb = $this->dbConnection->getQueryBuilder(); + $qb->select('*') + ->from('spreedme_room_participants') + ->where($qb->expr()->eq('sessionId', $qb->createNamedParameter($sessionId))) + ->andWhere($qb->expr()->eq('userId', $qb->createNamedParameter((string)$this->userId))); + $result = $qb->execute(); + $currentParticipant = $result->fetch(); + $result->closeCursor(); + + // Logged in user } else { $qb = $this->dbConnection->getQueryBuilder(); $qb->select('*') @@ -178,33 +182,40 @@ class SignallingController extends Controller { if ($sessionId === null) { // User is not active anywhere - $eventSource->send('usersInRoom', []); - } else { - // Check if the connection is still active, if not: Kill all existing - // messages and end the event source - if ($currentParticipant) { - try { - $room = $this->manager->getRoomForParticipant($currentParticipant['roomId'], $this->userId); - $eventSource->send('usersInRoom', $this->getUsersInRoom($room)); - } catch (RoomNotFoundException $e) { - $eventSource->send('usersInRoom', []); - } - } else { - $eventSource->send('usersInRoom', []); - } + $data[] = ['type' => 'usersInRoom', 'data' => []]; + break; + } - $messages = $this->messages->getAndDeleteMessages($sessionId); - foreach ($messages as $row) { - $eventSource->send('message', $row['data']); + // Check if the connection is still active, if not: Kill all existing + // messages and end the event source + if ($currentParticipant) { + try { + $room = $this->manager->getRoomForParticipant($currentParticipant['roomId'], $this->userId); + $data[] = ['type' => 'usersInRoom', 'data' => $this->getUsersInRoom($room)]; + } catch (RoomNotFoundException $e) { + $data[] = ['type' => 'usersInRoom', 'data' => []]; + break; } + } else { + $data[] = ['type' => 'usersInRoom', 'data' => []]; + break; + } + + $messages = $this->messages->getAndDeleteMessages($sessionId); + foreach ($messages as $row) { + $data[] = ['type' => 'message', 'data' => $row['data']]; } $this->dbConnection->close(); + if (empty($data) || $seconds <= 2) { + $seconds--; + } else { + $seconds = 2; + } sleep(1); } - $eventSource->close(); - exit; + return new DataResponse($data); } /** From 561bddb14dcebe2ef060e867b01b6d3ed5016427 Mon Sep 17 00:00:00 2001 From: Ivan Sein Date: Thu, 20 Jul 2017 12:03:42 +0200 Subject: [PATCH 07/21] Change js code to use new OCS endpoints. Signed-off-by: Ivan Sein --- js/signaling.js | 76 +++++++++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/js/signaling.js b/js/signaling.js index 8be9dba48..463e793c7 100644 --- a/js/signaling.js +++ b/js/signaling.js @@ -93,6 +93,7 @@ function InternalSignaling() { SignalingBase.prototype.constructor.apply(this, arguments); this.spreedArrayConnection = []; + this._startPullingMessages(); this.pingFails = 0; this.pingInterval = null; @@ -149,11 +150,18 @@ var message = [{ ev: ev }]; - $.post(OC.generateUrl('/apps/spreed/signalling'), { - messages: JSON.stringify(message) - }, function(data) { - this._trigger(ev, [data]); - }.bind(this)); + + $.ajax({ + url: OC.linkToOCS('apps/spreed/api/v1', 2) + 'signalling', + type: 'POST', + data: {messages: JSON.stringify(message)}, + beforeSend: function (request) { + request.setRequestHeader('Accept', 'application/json'); + }, + success: function (result) { + this._trigger(ev, [result.ocs.data]); + }.bind(this) + }); }; InternalSignaling.prototype.joinCall = function(token, callback, password) { @@ -288,27 +296,35 @@ /** * @private */ - InternalSignaling.prototype._openEventSource = function() { + InternalSignaling.prototype._startPullingMessages = function() { // Connect to the messages endpoint and pull for new messages - this.source = new OC.EventSource(OC.generateUrl('/apps/spreed/messages')); - - this.source.listen('usersInRoom', function(users) { - this._trigger('usersInRoom', [users]); - }.bind(this)); - this.source.listen('message', function(message) { - if (typeof(message) === 'string') { - message = JSON.parse(message); - } - this._trigger('message', [message]); - }.bind(this)); - this.source.listen('__internal__', function(data) { - if (data === 'close') { - console.log('signaling connection closed - will reopen'); - setTimeout(function() { - this._openEventSource(); - }.bind(this), 0); - } - }.bind(this)); + $.ajax({ + url: OC.linkToOCS('apps/spreed/api/v1', 2) + 'messages', + type: 'GET', + dataType: 'json', + beforeSend: function (request) { + request.setRequestHeader('Accept', 'application/json'); + }, + success: function (result) { + $.each(result.ocs.data, function(id, message) { + switch(message.type) { + case "usersInRoom": + this._trigger('usersInRoom', [message.data]); + break; + case "message": + if (typeof(message.data) === 'string') { + message.data = JSON.parse(message.data); + } + this._trigger('message', [message.data]); + break; + default: + console.log('Uknown Signalling Message'); + break; + } + }.bind(this)); + this._startPullingMessages(); + }.bind(this) + }); }; /** @@ -329,9 +345,15 @@ return; } - $.post(OC.generateUrl('/apps/spreed/signalling'), { - messages: JSON.stringify(this.spreedArrayConnection) + $.ajax({ + url: OC.linkToOCS('apps/spreed/api/v1', 2) + 'signalling', + type: 'POST', + data: {messages: JSON.stringify(this.spreedArrayConnection)}, + beforeSend: function (request) { + request.setRequestHeader('Accept', 'application/json'); + } }); + this.spreedArrayConnection = []; }; From a8aa4cb04f9d0c7c4caff77417265929415df2ea Mon Sep 17 00:00:00 2001 From: Ivan Sein Date: Mon, 24 Jul 2017 14:44:41 +0200 Subject: [PATCH 08/21] Unify sending messages into one method (rebased). Signed-off-by: Ivan Sein --- js/signaling.js | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/js/signaling.js b/js/signaling.js index 463e793c7..cc7980161 100644 --- a/js/signaling.js +++ b/js/signaling.js @@ -97,6 +97,7 @@ this.pingFails = 0; this.pingInterval = null; + this.isSendingMessages = false; this.sendInterval = window.setInterval(function(){ this.sendPendingMessages(); @@ -151,17 +152,31 @@ ev: ev }]; + this._sendMessages(message).done(function(result) { + this._trigger(ev, [result.ocs.data]); + }.bind(this)).fail(function(/*xhr, textStatus, errorThrown*/) { + console.log('Sending signalling message with callback has failed.'); + // TODO: Add error handling + }); + }; + + InternalSignaling.prototype._sendMessages = function(messages) { + var defer = $.Deferred(); $.ajax({ url: OC.linkToOCS('apps/spreed/api/v1', 2) + 'signalling', type: 'POST', - data: {messages: JSON.stringify(message)}, + data: {messages: JSON.stringify(messages)}, beforeSend: function (request) { request.setRequestHeader('Accept', 'application/json'); }, success: function (result) { - this._trigger(ev, [result.ocs.data]); - }.bind(this) + defer.resolve(result); + }, + error: function (xhr, textStatus, errorThrown) { + defer.reject(xhr, textStatus, errorThrown); + } }); + return defer; }; InternalSignaling.prototype.joinCall = function(token, callback, password) { @@ -341,20 +356,20 @@ * @private */ InternalSignaling.prototype.sendPendingMessages = function() { - if (!this.spreedArrayConnection.length) { + if (!this.spreedArrayConnection.length || this.isSendingMessages) { return; } - $.ajax({ - url: OC.linkToOCS('apps/spreed/api/v1', 2) + 'signalling', - type: 'POST', - data: {messages: JSON.stringify(this.spreedArrayConnection)}, - beforeSend: function (request) { - request.setRequestHeader('Accept', 'application/json'); - } - }); + var pendingMessagesLength = this.spreedArrayConnection.length; + this.isSendingMessages = true; - this.spreedArrayConnection = []; + this._sendMessages(this.spreedArrayConnection).done(function(result) { + this.spreedArrayConnection.splice(0, pendingMessagesLength); + this.isSendingMessages = false; + }.bind(this)).fail(function(/*xhr, textStatus, errorThrown*/) { + console.log('Sending pending signaling messages has failed.'); + this.isSendingMessages = false; + }.bind(this)); }; /** From 3f02e9d9c646671bb800f59157e46a6de2a2c9ca Mon Sep 17 00:00:00 2001 From: Ivan Sein Date: Mon, 24 Jul 2017 14:47:41 +0200 Subject: [PATCH 09/21] Remove 2 seconds wait pulling messages. Signed-off-by: Ivan Sein --- lib/Controller/SignallingController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Controller/SignallingController.php b/lib/Controller/SignallingController.php index 54ffd66c5..712b1eddf 100644 --- a/lib/Controller/SignallingController.php +++ b/lib/Controller/SignallingController.php @@ -207,10 +207,10 @@ class SignallingController extends OCSController { } $this->dbConnection->close(); - if (empty($data) || $seconds <= 2) { + if (empty($data)) { $seconds--; } else { - $seconds = 2; + break; } sleep(1); } From 294f3b6d27cdef14f89d0d18a04a862774dce447 Mon Sep 17 00:00:00 2001 From: Ivan Sein Date: Fri, 8 Sep 2017 16:49:32 +0200 Subject: [PATCH 10/21] Fix eslint. Signed-off-by: Ivan Sein --- js/signaling.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/js/signaling.js b/js/signaling.js index cc7980161..2042dfe8b 100644 --- a/js/signaling.js +++ b/js/signaling.js @@ -323,18 +323,18 @@ success: function (result) { $.each(result.ocs.data, function(id, message) { switch(message.type) { - case "usersInRoom": - this._trigger('usersInRoom', [message.data]); - break; - case "message": - if (typeof(message.data) === 'string') { + case "usersInRoom": + this._trigger('usersInRoom', [message.data]); + break; + case "message": + if (typeof(message.data) === 'string') { message.data = JSON.parse(message.data); } this._trigger('message', [message.data]); - break; - default: - console.log('Uknown Signalling Message'); - break; + break; + default: + console.log('Uknown Signalling Message'); + break; } }.bind(this)); this._startPullingMessages(); @@ -363,7 +363,7 @@ var pendingMessagesLength = this.spreedArrayConnection.length; this.isSendingMessages = true; - this._sendMessages(this.spreedArrayConnection).done(function(result) { + this._sendMessages(this.spreedArrayConnection).done(function(/*result*/) { this.spreedArrayConnection.splice(0, pendingMessagesLength); this.isSendingMessages = false; }.bind(this)).fail(function(/*xhr, textStatus, errorThrown*/) { From d23839df11329e68b3dd46c9aa3c6b21408e1e47 Mon Sep 17 00:00:00 2001 From: Ivan Sein Date: Tue, 12 Sep 2017 12:23:42 +0200 Subject: [PATCH 11/21] Retry after 5 seconds if pull messages failed. Signed-off-by: Ivan Sein --- js/signaling.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/js/signaling.js b/js/signaling.js index 2042dfe8b..6104cd00f 100644 --- a/js/signaling.js +++ b/js/signaling.js @@ -338,6 +338,12 @@ } }.bind(this)); this._startPullingMessages(); + }.bind(this), + error: function (/*jqXHR, textStatus, errorThrown*/) { + //Retry to pull messages after 5 seconds + window.setTimeout(function() { + this._startPullingMessages(); + }.bind(this), 5000); }.bind(this) }); }; From 9da1bf3343a2c7557087e6d2bb075f5532ab3b50 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 12 Sep 2017 18:11:33 +0200 Subject: [PATCH 12/21] Remove queries from controller Signed-off-by: Joas Schilling --- lib/Controller/SignallingController.php | 66 ++++++------------------- 1 file changed, 14 insertions(+), 52 deletions(-) diff --git a/lib/Controller/SignallingController.php b/lib/Controller/SignallingController.php index 712b1eddf..999d87795 100644 --- a/lib/Controller/SignallingController.php +++ b/lib/Controller/SignallingController.php @@ -28,6 +28,7 @@ use OCA\Spreed\Exceptions\RoomNotFoundException; use OCA\Spreed\Manager; use OCA\Spreed\Room; use OCA\Spreed\Signalling\Messages; +use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCSController; use OCP\IDBConnection; @@ -45,7 +46,7 @@ class SignallingController extends OCSController { private $dbConnection; /** @var Messages */ private $messages; - /** @var string */ + /** @var string|null */ private $userId; /** @@ -136,74 +137,35 @@ class SignallingController extends OCSController { * @return DataResponse */ public function pullMessages() { - set_time_limit(0); $data = []; $seconds = 30; while ($seconds > 0) { - // Guest if ($this->userId === null) { $sessionId = $this->session->get('spreed-session'); - - if ($sessionId === null) { - // User is not active anywhere; - $data[] = ['type' => 'usersInRoom', 'data' => []]; - break; - } - - $qb = $this->dbConnection->getQueryBuilder(); - $qb->select('*') - ->from('spreedme_room_participants') - ->where($qb->expr()->eq('sessionId', $qb->createNamedParameter($sessionId))) - ->andWhere($qb->expr()->eq('userId', $qb->createNamedParameter((string)$this->userId))); - $result = $qb->execute(); - $currentParticipant = $result->fetch(); - $result->closeCursor(); - - // Logged in user } else { - $qb = $this->dbConnection->getQueryBuilder(); - $qb->select('*') - ->from('spreedme_room_participants') - ->where($qb->expr()->neq('sessionId', $qb->createNamedParameter('0'))) - ->andWhere($qb->expr()->eq('userId', $qb->createNamedParameter((string)$this->userId))) - ->orderBy('lastPing', 'DESC') - ->setMaxResults(1); - $result = $qb->execute(); - $currentParticipant = $result->fetch(); - $result->closeCursor(); - - if ($currentParticipant === false) { - $sessionId = null; - } else { - $sessionId = $currentParticipant['sessionId']; - } + $sessionId = $this->manager->getCurrentSessionId($this->userId); } if ($sessionId === null) { // User is not active anywhere - $data[] = ['type' => 'usersInRoom', 'data' => []]; - break; + return new DataResponse([['type' => 'usersInRoom', 'data' => []]], Http::STATUS_NOT_FOUND); } - // Check if the connection is still active, if not: Kill all existing - // messages and end the event source - if ($currentParticipant) { + // Query all messages and send them to the user + $data = $this->messages->getAndDeleteMessages($sessionId); + $messageCount = count($data); + $data = array_filter($data, function($message) { + return $message['data'] !== 'refresh-participant-list'; + }); + + if ($messageCount !== count($data)) { try { - $room = $this->manager->getRoomForParticipant($currentParticipant['roomId'], $this->userId); + $room = $this->manager->getRoomForSession($this->userId, $sessionId); $data[] = ['type' => 'usersInRoom', 'data' => $this->getUsersInRoom($room)]; } catch (RoomNotFoundException $e) { - $data[] = ['type' => 'usersInRoom', 'data' => []]; - break; + return new DataResponse([['type' => 'usersInRoom', 'data' => []]], Http::STATUS_NOT_FOUND); } - } else { - $data[] = ['type' => 'usersInRoom', 'data' => []]; - break; - } - - $messages = $this->messages->getAndDeleteMessages($sessionId); - foreach ($messages as $row) { - $data[] = ['type' => 'message', 'data' => $row['data']]; } $this->dbConnection->close(); From 4aba050ddfcaa3d2415382dd27ff8410b4d5b615 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 14 Sep 2017 10:19:41 +0200 Subject: [PATCH 13/21] Allow to add a message for all participants in a room Signed-off-by: Joas Schilling --- lib/Signalling/Messages.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/Signalling/Messages.php b/lib/Signalling/Messages.php index 756ad95a2..d85f50dd7 100644 --- a/lib/Signalling/Messages.php +++ b/lib/Signalling/Messages.php @@ -22,6 +22,7 @@ namespace OCA\Spreed\Signalling; +use OCA\Spreed\Room; use OCP\AppFramework\Utility\ITimeFactory; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; @@ -73,6 +74,29 @@ class Messages { $query->execute(); } + /** + * @param Room $room + * @param string $message + */ + public function addMessageForAllParticipants(Room $room, $message) { + $query = $this->db->getQueryBuilder(); + $query->insert('videocalls_signalling') + ->values( + [ + 'sender' => $query->createParameter('sender'), + 'recipient' => $query->createParameter('recipient'), + 'timestamp' => $query->createNamedParameter($this->time->getTime()), + 'message' => $query->createNamedParameter($message), + ] + ); + + foreach ($room->getActiveSessions() as $sessionId) { + $query->setParameter('sender', $sessionId) + ->setParameter('recipient', $sessionId) + ->execute(); + } + } + /** * Get messages and delete them afterwards * From c0dce7345f7ab0e9972344f89a131dd53565fd1a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 14 Sep 2017 10:25:01 +0200 Subject: [PATCH 14/21] Listen to the join/leave event and refresh the list for all participants Signed-off-by: Joas Schilling --- appinfo/app.php | 3 +++ lib/AppInfo/Application.php | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/appinfo/app.php b/appinfo/app.php index 5b7f90be1..35b7e4fb8 100644 --- a/appinfo/app.php +++ b/appinfo/app.php @@ -19,6 +19,9 @@ * */ +$app = new \OCA\Spreed\AppInfo\Application(); +$app->registerHooks(); + // For the navigation $l->t('Video calls') $manager = \OC::$server->getNotificationManager(); diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 88450d170..8998a8c2d 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -21,7 +21,10 @@ namespace OCA\Spreed\AppInfo; +use OCA\Spreed\Room; +use OCA\Spreed\Signalling\Messages; use OCP\AppFramework\App; +use Symfony\Component\EventDispatcher\GenericEvent; class Application extends App { @@ -29,4 +32,18 @@ class Application extends App { parent::__construct('spreed', $urlParams); } + public function registerHooks() { + $listener = function(GenericEvent $event) { + /** @var Room $room */ + $room = $event->getSubject(); + + /** @var Messages $messages */ + $messages = $this->getContainer()->query(Messages::class); + $messages->addMessageForAllParticipants($room, 'refresh-participant-list'); + }; + + $dispatcher = $this->getContainer()->getServer()->getEventDispatcher(); + $dispatcher->addListener(Room::class . '::postUserEnterRoom', $listener); + $dispatcher->addListener(Room::class . '::postGuestEnterRoom', $listener); + } } From 288c1bb3211c75612a935b5413848092ea562b77 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 21 Sep 2017 11:26:37 +0200 Subject: [PATCH 15/21] Fix spelling of Signaling (single L) Signed-off-by: Joas Schilling --- appinfo/routes.php | 6 +++--- docs/api-v1.md | 6 +++--- js/signaling.js | 8 ++++---- js/simplewebrtc.js | 2 +- lib/AppInfo/Application.php | 2 +- lib/Controller/CallController.php | 2 +- ...nallingController.php => SignalingController.php} | 6 +++--- lib/Migration/Version2001Date20170913104501.php | 4 ++-- lib/{Signalling => Signaling}/Messages.php | 12 ++++++------ .../spreedcheats/lib/Controller/ApiController.php | 2 +- 10 files changed, 25 insertions(+), 25 deletions(-) rename lib/Controller/{SignallingController.php => SignalingController.php} (97%) rename lib/{Signalling => Signaling}/Messages.php (94%) diff --git a/appinfo/routes.php b/appinfo/routes.php index 9121be96e..2198836cb 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -36,15 +36,15 @@ return [ ], 'ocs' => [ [ - 'name' => 'Signalling#signalling', - 'url' => '/api/{apiVersion}/signalling', + 'name' => 'Signaling#signaling', + 'url' => '/api/{apiVersion}/signaling', 'verb' => 'POST', 'requirements' => [ 'apiVersion' => 'v1', ], ], [ - 'name' => 'Signalling#pullMessages', + 'name' => 'Signaling#pullMessages', 'url' => '/api/{apiVersion}/messages', 'verb' => 'GET', 'requirements' => [ diff --git a/docs/api-v1.md b/docs/api-v1.md index dbc943f91..72caa31ca 100644 --- a/docs/api-v1.md +++ b/docs/api-v1.md @@ -23,7 +23,7 @@ * [Join a call](#join-a-call) * [Send ping to keep the call alive](#send-ping-to-keep-the-call-alive) * [Leave a call (but staying in the room for future calls)](#leave-a-call--but-staying-in-the-room-for-future-calls-) -- [Signalling](#signalling) +- [Signaling](#signaling) Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1` @@ -351,6 +351,6 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1` + `200 OK` + `404 Not Found` When the room could not be found for the participant -## Signalling +## Signaling -To be defined +See the [Draft](https://github.com/nextcloud/spreed/wiki/Signaling-API) in the wiki… diff --git a/js/signaling.js b/js/signaling.js index 6104cd00f..71e54d4ae 100644 --- a/js/signaling.js +++ b/js/signaling.js @@ -155,7 +155,7 @@ this._sendMessages(message).done(function(result) { this._trigger(ev, [result.ocs.data]); }.bind(this)).fail(function(/*xhr, textStatus, errorThrown*/) { - console.log('Sending signalling message with callback has failed.'); + console.log('Sending signaling message with callback has failed.'); // TODO: Add error handling }); }; @@ -163,7 +163,7 @@ InternalSignaling.prototype._sendMessages = function(messages) { var defer = $.Deferred(); $.ajax({ - url: OC.linkToOCS('apps/spreed/api/v1', 2) + 'signalling', + url: OC.linkToOCS('apps/spreed/api/v1', 2) + 'signaling', type: 'POST', data: {messages: JSON.stringify(messages)}, beforeSend: function (request) { @@ -188,7 +188,7 @@ // 3. Pass information about the clients that need to be called by you to the callback. // // The clients will then use the message command to exchange - // their signalling information. + // their signaling information. $.ajax({ url: OC.linkToOCS('apps/spreed/api/v1/call', 2) + token, type: 'POST', @@ -333,7 +333,7 @@ this._trigger('message', [message.data]); break; default: - console.log('Uknown Signalling Message'); + console.log('Unknown Signaling Message'); break; } }.bind(this)); diff --git a/js/simplewebrtc.js b/js/simplewebrtc.js index cf41b4194..62b4d9e7a 100644 --- a/js/simplewebrtc.js +++ b/js/simplewebrtc.js @@ -17760,7 +17760,7 @@ } }; -// send via signalling channel +// send via signaling channel Peer.prototype.send = function (messageType, payload) { var message = { to: this.id, diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 8998a8c2d..4af2fa383 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -22,7 +22,7 @@ namespace OCA\Spreed\AppInfo; use OCA\Spreed\Room; -use OCA\Spreed\Signalling\Messages; +use OCA\Spreed\Signaling\Messages; use OCP\AppFramework\App; use Symfony\Component\EventDispatcher\GenericEvent; diff --git a/lib/Controller/CallController.php b/lib/Controller/CallController.php index 4710b4f74..224510de4 100644 --- a/lib/Controller/CallController.php +++ b/lib/Controller/CallController.php @@ -30,7 +30,7 @@ use OCA\Spreed\Exceptions\ParticipantNotFoundException; use OCA\Spreed\Exceptions\RoomNotFoundException; use OCA\Spreed\Manager; use OCA\Spreed\Participant; -use OCA\Spreed\Signalling\Messages; +use OCA\Spreed\Signaling\Messages; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCSController; diff --git a/lib/Controller/SignallingController.php b/lib/Controller/SignalingController.php similarity index 97% rename from lib/Controller/SignallingController.php rename to lib/Controller/SignalingController.php index 999d87795..44d215023 100644 --- a/lib/Controller/SignallingController.php +++ b/lib/Controller/SignalingController.php @@ -27,7 +27,7 @@ use OCA\Spreed\Config; use OCA\Spreed\Exceptions\RoomNotFoundException; use OCA\Spreed\Manager; use OCA\Spreed\Room; -use OCA\Spreed\Signalling\Messages; +use OCA\Spreed\Signaling\Messages; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCSController; @@ -35,7 +35,7 @@ use OCP\IDBConnection; use OCP\IRequest; use OCP\ISession; -class SignallingController extends OCSController { +class SignalingController extends OCSController { /** @var Config */ private $config; /** @var ISession */ @@ -82,7 +82,7 @@ class SignallingController extends OCSController { * @param string $messages * @return DataResponse */ - public function signalling($messages) { + public function signaling($messages) { $response = []; $messages = json_decode($messages, true); foreach($messages as $message) { diff --git a/lib/Migration/Version2001Date20170913104501.php b/lib/Migration/Version2001Date20170913104501.php index 3c6babff8..2559ad4c9 100644 --- a/lib/Migration/Version2001Date20170913104501.php +++ b/lib/Migration/Version2001Date20170913104501.php @@ -31,8 +31,8 @@ class Version2001Date20170913104501 extends SimpleMigrationStep { /** @var Schema $schema */ $schema = $schemaClosure(); - if (!$schema->hasTable('videocalls_signalling')) { - $table = $schema->createTable('videocalls_signalling'); + if (!$schema->hasTable('videocalls_signaling')) { + $table = $schema->createTable('videocalls_signaling'); $table->addColumn('sender', Type::STRING, [ 'notnull' => true, diff --git a/lib/Signalling/Messages.php b/lib/Signaling/Messages.php similarity index 94% rename from lib/Signalling/Messages.php rename to lib/Signaling/Messages.php index d85f50dd7..72d228cda 100644 --- a/lib/Signalling/Messages.php +++ b/lib/Signaling/Messages.php @@ -19,7 +19,7 @@ * */ -namespace OCA\Spreed\Signalling; +namespace OCA\Spreed\Signaling; use OCA\Spreed\Room; @@ -49,7 +49,7 @@ class Messages { */ public function deleteMessages(array $sessionIds) { $query = $this->db->getQueryBuilder(); - $query->delete('videocalls_signalling') + $query->delete('videocalls_signaling') ->where($query->expr()->in('recipient', $query->createNamedParameter($sessionIds, IQueryBuilder::PARAM_STR_ARRAY))) ->orWhere($query->expr()->in('sender', $query->createNamedParameter($sessionIds, IQueryBuilder::PARAM_STR_ARRAY))); $query->execute(); @@ -62,7 +62,7 @@ class Messages { */ public function addMessage($senderSessionId, $recipientSessionId, $message) { $query = $this->db->getQueryBuilder(); - $query->insert('videocalls_signalling') + $query->insert('videocalls_signaling') ->values( [ 'sender' => $query->createNamedParameter($senderSessionId), @@ -80,7 +80,7 @@ class Messages { */ public function addMessageForAllParticipants(Room $room, $message) { $query = $this->db->getQueryBuilder(); - $query->insert('videocalls_signalling') + $query->insert('videocalls_signaling') ->values( [ 'sender' => $query->createParameter('sender'), @@ -114,7 +114,7 @@ class Messages { $query = $this->db->getQueryBuilder(); $query->select('*') - ->from('videocalls_signalling') + ->from('videocalls_signaling') ->where($query->expr()->eq('recipient', $query->createNamedParameter($sessionId))) ->andWhere($query->expr()->lte('timestamp', $query->createNamedParameter($time))); $result = $query->execute(); @@ -125,7 +125,7 @@ class Messages { $result->closeCursor(); $query = $this->db->getQueryBuilder(); - $query->delete('videocalls_signalling') + $query->delete('videocalls_signaling') ->where($query->expr()->eq('recipient', $query->createNamedParameter($sessionId))) ->andWhere($query->expr()->lte('timestamp', $query->createNamedParameter($time))); $query->execute(); diff --git a/tests/integration/spreedcheats/lib/Controller/ApiController.php b/tests/integration/spreedcheats/lib/Controller/ApiController.php index b4d232f30..9fe3081b8 100644 --- a/tests/integration/spreedcheats/lib/Controller/ApiController.php +++ b/tests/integration/spreedcheats/lib/Controller/ApiController.php @@ -51,7 +51,7 @@ class ApiController extends OCSController { public function resetSpreed() { $query = $this->db->getQueryBuilder(); - $query->delete('videocalls_signalling')->execute(); + $query->delete('videocalls_signaling')->execute(); $query = $this->db->getQueryBuilder(); $query->delete('spreedme_rooms')->execute(); From 6150ac24f5d5d1af2c3f9d042798fc1ebbcf1df6 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 21 Sep 2017 11:30:05 +0200 Subject: [PATCH 16/21] Move "get messages" also to signaling route Signed-off-by: Joas Schilling --- appinfo/routes.php | 2 +- js/signaling.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index 2198836cb..688bc7763 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -45,7 +45,7 @@ return [ ], [ 'name' => 'Signaling#pullMessages', - 'url' => '/api/{apiVersion}/messages', + 'url' => '/api/{apiVersion}/signaling', 'verb' => 'GET', 'requirements' => [ 'apiVersion' => 'v1', diff --git a/js/signaling.js b/js/signaling.js index 71e54d4ae..277c3eb24 100644 --- a/js/signaling.js +++ b/js/signaling.js @@ -314,7 +314,7 @@ InternalSignaling.prototype._startPullingMessages = function() { // Connect to the messages endpoint and pull for new messages $.ajax({ - url: OC.linkToOCS('apps/spreed/api/v1', 2) + 'messages', + url: OC.linkToOCS('apps/spreed/api/v1', 2) + 'signaling', type: 'GET', dataType: 'json', beforeSend: function (request) { From 620a2c19a3d88cf1e357cc5bbdb36375bb8e740f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Sep 2017 11:12:49 +0200 Subject: [PATCH 17/21] Fix getRoomForSession with guests Signed-off-by: Joas Schilling --- lib/Manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Manager.php b/lib/Manager.php index 9dfe73272..de438263b 100644 --- a/lib/Manager.php +++ b/lib/Manager.php @@ -241,7 +241,7 @@ class Manager { } /** - * @param string $userId + * @param string|null $userId * @param string $sessionId * @return Room * @throws RoomNotFoundException From 2cf9d55e0fd933872e28446c5492296397aff988 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Sep 2017 14:25:40 +0200 Subject: [PATCH 18/21] Listen to more events Signed-off-by: Joas Schilling --- lib/AppInfo/Application.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 4af2fa383..7e2a2e752 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -45,5 +45,8 @@ class Application extends App { $dispatcher = $this->getContainer()->getServer()->getEventDispatcher(); $dispatcher->addListener(Room::class . '::postUserEnterRoom', $listener); $dispatcher->addListener(Room::class . '::postGuestEnterRoom', $listener); + $dispatcher->addListener(Room::class . '::postRemoveUser', $listener); + $dispatcher->addListener(Room::class . '::postRemoveBySession', $listener); + $dispatcher->addListener(Room::class . '::postPostUserDisconnectRoom', $listener); } } From 1e0db4151db773df54ec440d6937e86d916f4288 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Sep 2017 15:43:46 +0200 Subject: [PATCH 19/21] Fix conflict-resolution from long-polling vs. passwords Signed-off-by: Joas Schilling --- js/signaling.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/js/signaling.js b/js/signaling.js index 277c3eb24..37b2781a6 100644 --- a/js/signaling.js +++ b/js/signaling.js @@ -93,7 +93,6 @@ function InternalSignaling() { SignalingBase.prototype.constructor.apply(this, arguments); this.spreedArrayConnection = []; - this._startPullingMessages(); this.pingFails = 0; this.pingInterval = null; @@ -203,7 +202,7 @@ this.sessionId = result.ocs.data.sessionId; this.currentCallToken = token; this._startPingCall(); - this._openEventSource(); + this._startPullingMessages(); this._getCallPeers(token).then(function(peers) { var callDescription = { 'clients': {} From 5e353843a5ba84f42fa1c26ebf9a6aa196802120 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 26 Sep 2017 11:06:05 +0200 Subject: [PATCH 20/21] Fix event name Signed-off-by: Joas Schilling --- lib/AppInfo/Application.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 7e2a2e752..00eecba57 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -47,6 +47,6 @@ class Application extends App { $dispatcher->addListener(Room::class . '::postGuestEnterRoom', $listener); $dispatcher->addListener(Room::class . '::postRemoveUser', $listener); $dispatcher->addListener(Room::class . '::postRemoveBySession', $listener); - $dispatcher->addListener(Room::class . '::postPostUserDisconnectRoom', $listener); + $dispatcher->addListener(Room::class . '::postUserDisconnectRoom', $listener); } } From 4f9207b389a2f93da4b6e0512e9495c82e04142a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 26 Sep 2017 11:08:50 +0200 Subject: [PATCH 21/21] Make sure we send the user list at least all 30 seconds Signed-off-by: Joas Schilling --- lib/Controller/SignalingController.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/Controller/SignalingController.php b/lib/Controller/SignalingController.php index 44d215023..5186c02ba 100644 --- a/lib/Controller/SignalingController.php +++ b/lib/Controller/SignalingController.php @@ -139,6 +139,7 @@ class SignalingController extends OCSController { public function pullMessages() { $data = []; $seconds = 30; + $sessionId = ''; while ($seconds > 0) { if ($this->userId === null) { @@ -177,6 +178,13 @@ class SignalingController extends OCSController { sleep(1); } + try { + // Add an update of the room participants at the end of the waiting + $room = $this->manager->getRoomForSession($this->userId, $sessionId); + $data[] = ['type' => 'usersInRoom', 'data' => $this->getUsersInRoom($room)]; + } catch (RoomNotFoundException $e) { + } + return new DataResponse($data); }