improve realtime class
This commit is contained in:
parent
603f4ab99d
commit
111905514d
2 changed files with 79 additions and 57 deletions
|
@ -241,8 +241,6 @@ $server->on('open', function (Server $server, Request $request) use (&$connectio
|
|||
/** @var Appwrite\Database\Document $project */
|
||||
$project = $app->getResource('project');
|
||||
|
||||
$channels = $request->getQuery('channels', []);
|
||||
|
||||
/*
|
||||
* Abuse Check
|
||||
*/
|
||||
|
@ -271,52 +269,18 @@ $server->on('open', function (Server $server, Request $request) use (&$connectio
|
|||
|
||||
Realtime::setUser($user);
|
||||
|
||||
$roles = ['*', 'user:' . $user->getId(), 'role:' . (($user->isEmpty()) ? Auth::USER_ROLE_GUEST : Auth::USER_ROLE_MEMBER)];
|
||||
$channels = array_flip($channels);
|
||||
|
||||
Realtime::parseChannels($channels);
|
||||
Realtime::parseRoles($roles);
|
||||
$roles = Realtime::getRoles();
|
||||
$channels = Realtime::parseChannels($request->getQuery('channels', []));
|
||||
|
||||
/**
|
||||
* Channels Check
|
||||
*/
|
||||
if (empty($request->getQuery('channels', []))) {
|
||||
if (empty($channels)) {
|
||||
$server->push($connection, 'Missing channels');
|
||||
$server->close($connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Subscriptions Tree
|
||||
*
|
||||
* [PROJECT_ID] ->
|
||||
* [ROLE_X] ->
|
||||
* [CHANNEL_NAME_X] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Y] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Z] -> [CONNECTION_ID]
|
||||
* [ROLE_Y] ->
|
||||
* [CHANNEL_NAME_X] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Y] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Z] -> [CONNECTION_ID]
|
||||
*/
|
||||
|
||||
if (!isset($subscriptions[$project->getId()])) { // Init Project
|
||||
$subscriptions[$project->getId()] = [];
|
||||
}
|
||||
|
||||
foreach ($roles as $key => $role) {
|
||||
if (!isset($subscriptions[$project->getId()][$role])) { // Add user first connection
|
||||
$subscriptions[$project->getId()][$role] = [];
|
||||
}
|
||||
|
||||
foreach ($channels as $channel => $list) {
|
||||
$subscriptions[$project->getId()][$role][$channel][$connection] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$connections[$connection] = [
|
||||
'projectId' => $project->getId(),
|
||||
'roles' => $roles,
|
||||
];
|
||||
Realtime::addSubscription($project->getId(), $connection, $subscriptions, $connections, $roles, $channels);
|
||||
|
||||
$server->push($connection, json_encode($channels));
|
||||
});
|
||||
|
@ -330,6 +294,9 @@ $server->on('message', function (Server $server, Frame $frame) {
|
|||
});
|
||||
|
||||
$server->on('close', function (Server $server, int $fd) use (&$connections, &$subscriptions) {
|
||||
/**
|
||||
* TODO: Move into Realtime Class for tests
|
||||
*/
|
||||
$projectId = $connections[$fd]['projectId'] ?? '';
|
||||
$roles = $connections[$fd]['roles'] ?? [];
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Appwrite\Realtime;
|
||||
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Database\Document;
|
||||
|
||||
class Realtime
|
||||
|
@ -19,11 +20,34 @@ class Realtime
|
|||
self::$user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
static function getRoles()
|
||||
{
|
||||
$roles = ['*', 'role:' . ((self::$user->isEmpty()) ? Auth::USER_ROLE_GUEST : Auth::USER_ROLE_MEMBER)];
|
||||
if (!(self::$user->isEmpty())) {
|
||||
$roles[] = 'user:' . self::$user->getId();
|
||||
}
|
||||
foreach (self::$user->getAttribute('memberships', []) as $node) {
|
||||
if (isset($node['teamId']) && isset($node['roles'])) {
|
||||
$roles[] = 'team:' . $node['teamId'];
|
||||
|
||||
foreach ($node['roles'] as $nodeRole) { // Set all team roles
|
||||
$roles[] = 'team:' . $node['teamId'] . '/' . $nodeRole;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $channels
|
||||
*/
|
||||
static function parseChannels(array &$channels)
|
||||
static function parseChannels(array $channels)
|
||||
{
|
||||
$channels = array_flip($channels);
|
||||
|
||||
foreach ($channels as $key => $value) {
|
||||
if (strpos($key, 'account.') === 0) {
|
||||
unset($channels[$key]);
|
||||
|
@ -41,22 +65,8 @@ class Realtime
|
|||
}
|
||||
unset($channels['account']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $roles
|
||||
*/
|
||||
static function parseRoles(array &$roles)
|
||||
{
|
||||
\array_map(function ($node) use (&$roles) {
|
||||
if (isset($node['teamId']) && isset($node['roles'])) {
|
||||
$roles[] = 'team:' . $node['teamId'];
|
||||
|
||||
foreach ($node['roles'] as $nodeRole) { // Set all team roles
|
||||
$roles[] = 'team:' . $node['teamId'] . '/' . $nodeRole;
|
||||
}
|
||||
}
|
||||
}, self::$user->getAttribute('memberships', []));
|
||||
return $channels;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -90,4 +100,49 @@ class Realtime
|
|||
|
||||
return array_keys(array_flip($receivers));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Subscription.
|
||||
*
|
||||
* @param string $projectId
|
||||
* @param mixed $connection
|
||||
* @param array $subscriptions
|
||||
* @param array $roles
|
||||
* @param array $channels
|
||||
*/
|
||||
static function addSubscription($projectId, $connection, &$subscriptions, &$connections, &$roles, &$channels)
|
||||
{
|
||||
/**
|
||||
* Build Subscriptions Tree
|
||||
*
|
||||
* [PROJECT_ID] ->
|
||||
* [ROLE_X] ->
|
||||
* [CHANNEL_NAME_X] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Y] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Z] -> [CONNECTION_ID]
|
||||
* [ROLE_Y] ->
|
||||
* [CHANNEL_NAME_X] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Y] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Z] -> [CONNECTION_ID]
|
||||
*/
|
||||
|
||||
if (!isset($subscriptions[$projectId])) { // Init Project
|
||||
$subscriptions[$projectId] = [];
|
||||
}
|
||||
|
||||
foreach ($roles as $key => $role) {
|
||||
if (!isset($subscriptions[$projectId][$role])) { // Add user first connection
|
||||
$subscriptions[$projectId][$role] = [];
|
||||
}
|
||||
|
||||
foreach ($channels as $channel => $list) {
|
||||
$subscriptions[$projectId][$role][$channel][$connection] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$connections[$connection] = [
|
||||
'projectId' => $projectId,
|
||||
'roles' => $roles,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue