Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.

Commit 5890659

Browse files
committed
Refactored the dashboard logger
1 parent 38b2e4d commit 5890659

File tree

6 files changed

+160
-169
lines changed

6 files changed

+160
-169
lines changed

src/Dashboard/DashboardLogger.php

Lines changed: 35 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -10,119 +10,54 @@ class DashboardLogger
1010
{
1111
const LOG_CHANNEL_PREFIX = 'private-websockets-dashboard-';
1212

13-
const TYPE_DISCONNECTION = 'disconnection';
13+
const TYPE_DISCONNECTED = 'disconnected';
1414

15-
const TYPE_CONNECTION = 'connection';
15+
const TYPE_CONNECTED = 'connected';
1616

1717
const TYPE_VACATED = 'vacated';
1818

1919
const TYPE_OCCUPIED = 'occupied';
2020

2121
const TYPE_SUBSCRIBED = 'subscribed';
2222

23-
const TYPE_CLIENT_MESSAGE = 'client-message';
23+
const TYPE_WS_MESSAGE = 'ws-message';
2424

2525
const TYPE_API_MESSAGE = 'api-message';
2626

2727
const TYPE_REPLICATOR_SUBSCRIBED = 'replicator-subscribed';
2828

2929
const TYPE_REPLICATOR_UNSUBSCRIBED = 'replicator-unsubscribed';
3030

31-
public static function connection(ConnectionInterface $connection)
32-
{
33-
/** @var \GuzzleHttp\Psr7\Request $request */
34-
$request = $connection->httpRequest;
35-
36-
static::log($connection->app->id, static::TYPE_CONNECTION, [
37-
'details' => [
38-
'origin' => "{$request->getUri()->getScheme()}://{$request->getUri()->getHost()}",
39-
'socketId' => $connection->socketId,
40-
],
41-
]);
42-
}
43-
44-
public static function occupied(ConnectionInterface $connection, string $channelName)
45-
{
46-
static::log($connection->app->id, static::TYPE_OCCUPIED, [
47-
'details' => [
48-
'channel' => $channelName,
49-
],
50-
]);
51-
}
52-
53-
public static function subscribed(ConnectionInterface $connection, string $channelName)
54-
{
55-
static::log($connection->app->id, static::TYPE_SUBSCRIBED, [
56-
'details' => [
57-
'socketId' => $connection->socketId,
58-
'channel' => $channelName,
59-
],
60-
]);
61-
}
62-
63-
public static function clientMessage(ConnectionInterface $connection, stdClass $payload)
64-
{
65-
static::log($connection->app->id, static::TYPE_CLIENT_MESSAGE, [
66-
'details' => [
67-
'socketId' => $connection->socketId,
68-
'channel' => $payload->channel,
69-
'event' => $payload->event,
70-
'data' => $payload,
71-
],
72-
]);
73-
}
74-
75-
public static function disconnection(ConnectionInterface $connection)
76-
{
77-
static::log($connection->app->id, static::TYPE_DISCONNECTION, [
78-
'details' => [
79-
'socketId' => $connection->socketId,
80-
],
81-
]);
82-
}
83-
84-
public static function vacated(ConnectionInterface $connection, string $channelName)
85-
{
86-
static::log($connection->app->id, static::TYPE_VACATED, [
87-
'details' => [
88-
'socketId' => $connection->socketId,
89-
'channel' => $channelName,
90-
],
91-
]);
92-
}
93-
94-
public static function apiMessage($appId, string $channel, string $event, string $payload)
95-
{
96-
static::log($appId, static::TYPE_API_MESSAGE, [
97-
'details' => [
98-
'channel' => $connection,
99-
'event' => $event,
100-
'payload' => $payload,
101-
],
102-
]);
103-
}
104-
105-
public static function replicatorSubscribed(string $appId, string $channel, string $serverId)
106-
{
107-
static::log($appId, static::TYPE_REPLICATOR_SUBSCRIBED, [
108-
'details' => [
109-
'serverId' => $serverId,
110-
'channel' => $channel,
111-
],
112-
]);
113-
}
114-
115-
public static function replicatorUnsubscribed(string $appId, string $channel, string $serverId)
116-
{
117-
static::log($appId, static::TYPE_REPLICATOR_UNSUBSCRIBED, [
118-
'details' => [
119-
'serverId' => $serverId,
120-
'channel' => $channel,
121-
],
122-
]);
123-
}
124-
125-
public static function log($appId, string $type, array $attributes = [])
31+
const TYPE_REPLICATOR_JOINED_CHANNEL = 'replicator-joined';
32+
33+
const TYPE_REPLICATOR_LEFT_CHANNEL = 'replicator-left';
34+
35+
const TYPE_REPLICATOR_MESSAGE_PUBLISHED = 'replicator-message-published';
36+
37+
const TYPE_REPLICATOR_MESSAGE_RECEIVED = 'replicator-message-received';
38+
39+
/**
40+
* The list of all channels.
41+
*
42+
* @var array
43+
*/
44+
public static $channels = [
45+
self::TYPE_DISCONNECTED,
46+
self::TYPE_CONNECTED,
47+
self::TYPE_VACATED,
48+
self::TYPE_OCCUPIED,
49+
self::TYPE_SUBSCRIBED,
50+
self::TYPE_WS_MESSAGE,
51+
self::TYPE_API_MESSAGE,
52+
self::TYPE_REPLICATOR_SUBSCRIBED,
53+
self::TYPE_REPLICATOR_UNSUBSCRIBED,
54+
self::TYPE_REPLICATOR_JOINED_CHANNEL,
55+
self::TYPE_REPLICATOR_LEFT_CHANNEL,
56+
self::TYPE_REPLICATOR_MESSAGE_PUBLISHED,
57+
self::TYPE_REPLICATOR_MESSAGE_RECEIVED,
58+
];
59+
60+
public static function log($appId, string $type, array $details = [])
12661
{
12762
$channelName = static::LOG_CHANNEL_PREFIX.$type;
12863

@@ -134,7 +69,8 @@ public static function log($appId, string $type, array $attributes = [])
13469
'data' => [
13570
'type' => $type,
13671
'time' => strftime('%H:%M:%S'),
137-
] + $attributes,
72+
'details' => $details,
73+
],
13874
]);
13975
}
14076
}

src/HttpApi/Controllers/TriggerEventController.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@ public function __invoke(Request $request)
2121
'data' => $request->json()->get('data'),
2222
], $request->json()->get('socket_id'), $request->appId);
2323

24-
DashboardLogger::apiMessage(
25-
$request->appId,
26-
$channelName,
27-
$request->json()->get('name'),
28-
$request->json()->get('data')
29-
);
24+
DashboardLogger::log($request->appId, DashboardLogger::TYPE_API_MESSAGE, [
25+
'channel' => $channelName,
26+
'event' => $request->json()->get('name'),
27+
'payload' => $request->json()->get('data'),
28+
]);
3029

3130
StatisticsLogger::apiMessage($request->appId);
3231
}

src/PubSub/Drivers/RedisClient.php

Lines changed: 94 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
use React\Promise\PromiseInterface;
1313
use stdClass;
1414

15-
class RedisClient implements ReplicationInterface
15+
class RedisClient extends LocalClient
1616
{
1717
/**
1818
* The running loop.
@@ -90,49 +90,29 @@ public function boot(LoopInterface $loop, $factoryClass = null): ReplicationInte
9090
}
9191

9292
/**
93-
* Handle a message received from Redis on a specific channel.
93+
* Publish a message to a channel on behalf of a websocket user.
9494
*
95-
* @param string $redisChannel
96-
* @param string $payload
97-
* @return void
95+
* @param string $appId
96+
* @param string $channel
97+
* @param stdClass $payload
98+
* @return bool
9899
*/
99-
protected function onMessage(string $redisChannel, string $payload)
100+
public function publish(string $appId, string $channel, stdClass $payload): bool
100101
{
101-
$payload = json_decode($payload);
102-
103-
// Ignore messages sent by ourselves.
104-
if (isset($payload->serverId) && $this->serverId === $payload->serverId) {
105-
return;
106-
}
107-
108-
// Pull out the app ID. See RedisPusherBroadcaster
109-
$appId = $payload->appId;
110-
111-
// We need to put the channel name in the payload.
112-
// We strip the app ID from the channel name, websocket clients
113-
// expect the channel name to not include the app ID.
114-
$payload->channel = Str::after($redisChannel, "{$appId}:");
115-
116-
$channelManager = app(ChannelManager::class);
117-
118-
// Load the Channel instance to sync.
119-
$channel = $channelManager->find($appId, $payload->channel);
102+
$payload->appId = $appId;
103+
$payload->serverId = $this->getServerId();
120104

121-
// If no channel is found, none of our connections want to
122-
// receive this message, so we ignore it.
123-
if (! $channel) {
124-
return;
125-
}
105+
$payload = json_encode($payload);
126106

127-
$socket = $payload->socket ?? null;
107+
$this->publishClient->__call('publish', ["$appId:$channel", $payload]);
128108

129-
// Remove fields intended for internal use from the payload.
130-
unset($payload->socket);
131-
unset($payload->serverId);
132-
unset($payload->appId);
109+
DashboardLogger::log($appId, DashboardLogger::TYPE_REPLICATOR_MESSAGE_PUBLISHED, [
110+
'channel' => $channel,
111+
'serverId' => $this->getServerId(),
112+
'payload' => $payload,
113+
]);
133114

134-
// Push the message out to connected websocket clients.
135-
$channel->broadcastToEveryoneExcept($payload, $socket, $appId, false);
115+
return true;
136116
}
137117

138118
/**
@@ -153,7 +133,10 @@ public function subscribe(string $appId, string $channel): bool
153133
$this->subscribedChannels["$appId:$channel"]++;
154134
}
155135

156-
DashboardLogger::replicatorSubscribed($appId, $channel, $this->serverId);
136+
DashboardLogger::log($appId, DashboardLogger::TYPE_REPLICATOR_SUBSCRIBED, [
137+
'channel' => $channel,
138+
'serverId' => $this->getServerId(),
139+
]);
157140

158141
return true;
159142
}
@@ -181,25 +164,10 @@ public function unsubscribe(string $appId, string $channel): bool
181164
unset($this->subscribedChannels["$appId:$channel"]);
182165
}
183166

184-
DashboardLogger::replicatorUnsubscribed($appId, $channel, $this->serverId);
185-
186-
return true;
187-
}
188-
189-
/**
190-
* Publish a message to a channel on behalf of a websocket user.
191-
*
192-
* @param string $appId
193-
* @param string $channel
194-
* @param stdClass $payload
195-
* @return bool
196-
*/
197-
public function publish(string $appId, string $channel, stdClass $payload): bool
198-
{
199-
$payload->appId = $appId;
200-
$payload->serverId = $this->serverId;
201-
202-
$this->publishClient->__call('publish', ["$appId:$channel", json_encode($payload)]);
167+
DashboardLogger::log($appId, DashboardLogger::TYPE_REPLICATOR_UNSUBSCRIBED, [
168+
'channel' => $channel,
169+
'serverId' => $this->getServerId(),
170+
]);
203171

204172
return true;
205173
}
@@ -217,6 +185,13 @@ public function publish(string $appId, string $channel, stdClass $payload): bool
217185
public function joinChannel(string $appId, string $channel, string $socketId, string $data)
218186
{
219187
$this->publishClient->__call('hset', ["$appId:$channel", $socketId, $data]);
188+
189+
DashboardLogger::log($appId, DashboardLogger::TYPE_REPLICATOR_JOINED_CHANNEL, [
190+
'channel' => $channel,
191+
'serverId' => $this->getServerId(),
192+
'socketId' => $socketId,
193+
'data' => $data,
194+
]);
220195
}
221196

222197
/**
@@ -231,6 +206,12 @@ public function joinChannel(string $appId, string $channel, string $socketId, st
231206
public function leaveChannel(string $appId, string $channel, string $socketId)
232207
{
233208
$this->publishClient->__call('hdel', ["$appId:$channel", $socketId]);
209+
210+
DashboardLogger::log($appId, DashboardLogger::TYPE_REPLICATOR_LEFT_CHANNEL, [
211+
'channel' => $channel,
212+
'serverId' => $this->getServerId(),
213+
'socketId' => $socketId,
214+
]);
234215
}
235216

236217
/**
@@ -272,6 +253,62 @@ public function channelMemberCounts(string $appId, array $channelNames): Promise
272253
});
273254
}
274255

256+
/**
257+
* Handle a message received from Redis on a specific channel.
258+
*
259+
* @param string $redisChannel
260+
* @param string $payload
261+
* @return void
262+
*/
263+
protected function onMessage(string $redisChannel, string $payload)
264+
{
265+
$payload = json_decode($payload);
266+
267+
// Ignore messages sent by ourselves.
268+
if (isset($payload->serverId) && $this->getServerId() === $payload->serverId) {
269+
return;
270+
}
271+
272+
// Pull out the app ID. See RedisPusherBroadcaster
273+
$appId = $payload->appId;
274+
275+
// We need to put the channel name in the payload.
276+
// We strip the app ID from the channel name, websocket clients
277+
// expect the channel name to not include the app ID.
278+
$payload->channel = Str::after($redisChannel, "{$appId}:");
279+
280+
$channelManager = app(ChannelManager::class);
281+
282+
// Load the Channel instance to sync.
283+
$channel = $channelManager->find($appId, $payload->channel);
284+
285+
// If no channel is found, none of our connections want to
286+
// receive this message, so we ignore it.
287+
if (! $channel) {
288+
return;
289+
}
290+
291+
$socket = $payload->socket ?? null;
292+
$serverId = $payload->serverId ?? null;
293+
294+
// Remove fields intended for internal use from the payload.
295+
unset($payload->socket);
296+
unset($payload->serverId);
297+
unset($payload->appId);
298+
299+
// Push the message out to connected websocket clients.
300+
$channel->broadcastToEveryoneExcept($payload, $socket, $appId, false);
301+
302+
DashboardLogger::log($appId, DashboardLogger::TYPE_REPLICATOR_MESSAGE_RECEIVED, [
303+
'channel' => $channel->getChannelName(),
304+
'redisChannel' => $redisChannel,
305+
'serverId' => $this->getServer(),
306+
'incomingServerId' => $serverId,
307+
'incomingSocketId' => $socket,
308+
'payload' => $payload,
309+
]);
310+
}
311+
275312
/**
276313
* Build the Redis connection URL from Laravel database config.
277314
*

0 commit comments

Comments
 (0)