add channels to realtime response
This commit is contained in:
parent
8869fac629
commit
a70cb90be1
|
@ -19,10 +19,7 @@ use Utopia\CLI\Console;
|
||||||
use Utopia\Config\Config;
|
use Utopia\Config\Config;
|
||||||
use Utopia\Registry\Registry;
|
use Utopia\Registry\Registry;
|
||||||
use Utopia\Swoole\Request as SwooleRequest;
|
use Utopia\Swoole\Request as SwooleRequest;
|
||||||
|
|
||||||
use PDO as PDONative;
|
use PDO as PDONative;
|
||||||
use Swoole\Database\RedisConfig;
|
|
||||||
use Swoole\Database\RedisPool;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO List
|
* TODO List
|
||||||
|
@ -114,9 +111,7 @@ $server->on("workerStart", function ($server, $workerId) use (&$subscriptions, &
|
||||||
Console::error('Pub/sub failed (worker: ' . $workerId . ')');
|
Console::error('Pub/sub failed (worker: ' . $workerId . ')');
|
||||||
}
|
}
|
||||||
|
|
||||||
$redis->subscribe(['realtime'], function ($redis, $channel, $payload) use ($server, $workerId, &$connections, &$subscriptions) {
|
$redis->subscribe(['realtime'], function ($redis, $channel, $payload) use ($server, &$connections, &$subscriptions) {
|
||||||
// TODO get project and resource ID and itterate over the resource read(?) permissions and send a message to all listeners
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Supported Resources:
|
* Supported Resources:
|
||||||
* - Collection
|
* - Collection
|
||||||
|
@ -130,20 +125,22 @@ $server->on("workerStart", function ($server, $workerId) use (&$subscriptions, &
|
||||||
* - Function
|
* - Function
|
||||||
* - Execution
|
* - Execution
|
||||||
*/
|
*/
|
||||||
$event = json_decode($payload);
|
$event = json_decode($payload, true);
|
||||||
|
|
||||||
$receivers = [];
|
$receivers = [];
|
||||||
|
|
||||||
foreach ($connections as $fd => $connection) {
|
foreach ($connections as $fd => $connection) {
|
||||||
if ($connection['projectId'] !== $event->project) {
|
if ($connection['projectId'] !== $event['project']) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($connection['roles'] as $role) {
|
foreach ($connection['roles'] as $role) {
|
||||||
if (\array_key_exists($role, $subscriptions[$event->project])) {
|
if (\array_key_exists($role, $subscriptions[$event['project']])) {
|
||||||
foreach ($event->channels as $channel) {
|
foreach ($event['data']['channels'] as $channel) {
|
||||||
if (\array_key_exists($channel, $subscriptions[$event->project][$role]) && \in_array($role, $event->permissions)) {
|
if (\array_key_exists($channel, $subscriptions[$event['project']][$role]) && \in_array($role, $event['permissions'])) {
|
||||||
$receivers = array_merge($receivers, array_keys($subscriptions[$event->project][$role][$channel]));
|
foreach (array_keys($subscriptions[$event['project']][$role][$channel]) as $ids) {
|
||||||
|
$receivers[] = $ids;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,13 +151,14 @@ $server->on("workerStart", function ($server, $workerId) use (&$subscriptions, &
|
||||||
$receivers = array_keys(array_flip($receivers));
|
$receivers = array_keys(array_flip($receivers));
|
||||||
|
|
||||||
foreach ($receivers as $receiver) {
|
foreach ($receivers as $receiver) {
|
||||||
if ($server->exist($receiver)
|
if ($server->exist($receiver) && $server->isEstablished($receiver)) {
|
||||||
&& $server->isEstablished($receiver)
|
$server->push(
|
||||||
) {
|
$receiver,
|
||||||
$server->push($receiver, json_encode($event->data), SWOOLE_WEBSOCKET_OPCODE_TEXT,
|
json_encode($event['data']),
|
||||||
SWOOLE_WEBSOCKET_FLAG_FIN | SWOOLE_WEBSOCKET_FLAG_COMPRESS);
|
SWOOLE_WEBSOCKET_OPCODE_TEXT,
|
||||||
}
|
SWOOLE_WEBSOCKET_FLAG_FIN | SWOOLE_WEBSOCKET_FLAG_COMPRESS
|
||||||
else {
|
);
|
||||||
|
} else {
|
||||||
$server->close($receiver);
|
$server->close($receiver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,13 +252,26 @@ $server->on('open', function (Server $server, Request $request) use (&$connectio
|
||||||
return $user;
|
return $user;
|
||||||
}, ['project', 'request', 'projectDB']);
|
}, ['project', 'request', 'projectDB']);
|
||||||
|
|
||||||
$channels = array_flip($request->getQuery('channels', []));
|
|
||||||
$user = $app->getResource('user');
|
|
||||||
$project = $app->getResource('project');
|
|
||||||
$roles = ['*', 'user:' . $user->getId(), 'role:' . (($user->isEmpty()) ? Auth::USER_ROLE_GUEST : Auth::USER_ROLE_MEMBER)];
|
|
||||||
|
|
||||||
/** @var Appwrite\Database\Document $user */
|
/** @var Appwrite\Database\Document $user */
|
||||||
|
$user = $app->getResource('user');
|
||||||
|
|
||||||
/** @var Appwrite\Database\Document $project */
|
/** @var Appwrite\Database\Document $project */
|
||||||
|
$project = $app->getResource('project');
|
||||||
|
|
||||||
|
$channels = $request->getQuery('channels', []);
|
||||||
|
|
||||||
|
if (empty($project->getId())) {
|
||||||
|
$server->push($connection, 'Missing or unknown project ID');
|
||||||
|
$server->close($connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($request->getQuery('channels', []))) {
|
||||||
|
$server->push($connection, 'Missing or unknown channels');
|
||||||
|
$server->close($connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
$roles = ['*', 'user:' . $user->getId(), 'role:' . (($user->isEmpty()) ? Auth::USER_ROLE_GUEST : Auth::USER_ROLE_MEMBER)];
|
||||||
|
$channels = array_flip($channels);
|
||||||
|
|
||||||
\array_map(function ($node) use (&$roles) {
|
\array_map(function ($node) use (&$roles) {
|
||||||
if (isset($node['teamId']) && isset($node['roles'])) {
|
if (isset($node['teamId']) && isset($node['roles'])) {
|
||||||
|
@ -304,11 +315,9 @@ $server->on('open', function (Server $server, Request $request) use (&$connectio
|
||||||
'projectId' => $project->getId(),
|
'projectId' => $project->getId(),
|
||||||
'roles' => $roles,
|
'roles' => $roles,
|
||||||
];
|
];
|
||||||
|
|
||||||
$server->push($connection, json_encode($subscriptions));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$server->on('message', function (Server $server, Frame $frame) use (&$connections, &$subscriptions) {
|
$server->on('message', function (Server $server, Frame $frame) {
|
||||||
if ($frame->data === 'reload') {
|
if ($frame->data === 'reload') {
|
||||||
$server->reload();
|
$server->reload();
|
||||||
}
|
}
|
||||||
|
@ -341,7 +350,6 @@ $server->on('close', function (Server $server, int $fd) use (&$connections, &$su
|
||||||
unset($connections[$fd]);
|
unset($connections[$fd]);
|
||||||
|
|
||||||
Console::info('Connection close: ' . $fd);
|
Console::info('Connection close: ' . $fd);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$server->start();
|
$server->start();
|
|
@ -141,10 +141,10 @@ class Realtime
|
||||||
$redis->connect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', ''));
|
$redis->connect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', ''));
|
||||||
$redis->publish('realtime', json_encode([
|
$redis->publish('realtime', json_encode([
|
||||||
'project' => $this->project,
|
'project' => $this->project,
|
||||||
'channels' => $this->channels,
|
|
||||||
'permissions' => $this->payload->getAttribute('$permissions.read'),
|
'permissions' => $this->payload->getAttribute('$permissions.read'),
|
||||||
'data' => [
|
'data' => [
|
||||||
'event' => $this->event,
|
'event' => $this->event,
|
||||||
|
'channels' => $this->channels,
|
||||||
'timestamp' => time(),
|
'timestamp' => time(),
|
||||||
'payload' => $this->payload->getArrayCopy()
|
'payload' => $this->payload->getArrayCopy()
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue