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

Commit 1f6e714

Browse files
authored
Merge pull request #544 from beyondcode/feature/promises
[2.x] Ensure promises run one-after-another
2 parents bf47275 + 60c21f3 commit 1f6e714

14 files changed

+397
-308
lines changed

config/websockets.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,4 +279,19 @@
279279

280280
],
281281

282+
/*
283+
|--------------------------------------------------------------------------
284+
| Promise Resolver
285+
|--------------------------------------------------------------------------
286+
|
287+
| The promise resolver is a class that takes a input value and is
288+
| able to make sure the PHP code runs async by using ->then(). You can
289+
| use your own Promise Resolver. This is usually changed when you want to
290+
| intercept values by the promises throughout the app, like in testing
291+
| to switch from async to sync.
292+
|
293+
*/
294+
295+
'promise_resolver' => \React\Promise\FulfilledPromise::class,
296+
282297
];

src/API/FetchChannels.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,9 @@ public function __invoke(Request $request)
6464
}
6565

6666
return $info;
67-
})
68-
->sortBy(function ($content, $name) {
67+
})->sortBy(function ($content, $name) {
6968
return $name;
70-
})
71-
->all();
69+
})->all();
7270

7371
return [
7472
'channels' => $channels ?: new stdClass,

src/ChannelManagers/LocalChannelManager.php

Lines changed: 60 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
use BeyondCode\LaravelWebSockets\Channels\PresenceChannel;
77
use BeyondCode\LaravelWebSockets\Channels\PrivateChannel;
88
use BeyondCode\LaravelWebSockets\Contracts\ChannelManager;
9+
use BeyondCode\LaravelWebSockets\Helpers;
910
use Illuminate\Support\Str;
1011
use Ratchet\ConnectionInterface;
1112
use React\EventLoop\LoopInterface;
12-
use React\Promise\FulfilledPromise;
1313
use React\Promise\PromiseInterface;
1414
use stdClass;
1515

@@ -104,7 +104,7 @@ public function getLocalConnections(): PromiseInterface
104104
->values()->collapse()
105105
->toArray();
106106

107-
return new FulfilledPromise($connections);
107+
return Helpers::createFulfilledPromise($connections);
108108
}
109109

110110
/**
@@ -116,7 +116,7 @@ public function getLocalConnections(): PromiseInterface
116116
*/
117117
public function getLocalChannels($appId): PromiseInterface
118118
{
119-
return new FulfilledPromise(
119+
return Helpers::createFulfilledPromise(
120120
$this->channels[$appId] ?? []
121121
);
122122
}
@@ -137,12 +137,12 @@ public function getGlobalChannels($appId): PromiseInterface
137137
* Remove connection from all channels.
138138
*
139139
* @param \Ratchet\ConnectionInterface $connection
140-
* @return void
140+
* @return PromiseInterface[bool]
141141
*/
142-
public function unsubscribeFromAllChannels(ConnectionInterface $connection)
142+
public function unsubscribeFromAllChannels(ConnectionInterface $connection): PromiseInterface
143143
{
144144
if (! isset($connection->app)) {
145-
return;
145+
return new FuilfilledPromise(false);
146146
}
147147

148148
$this->getLocalChannels($connection->app->id)
@@ -162,6 +162,8 @@ public function unsubscribeFromAllChannels(ConnectionInterface $connection)
162162
unset($this->channels[$connection->app->id]);
163163
}
164164
});
165+
166+
return Helpers::createFulfilledPromise(true);
165167
}
166168

167169
/**
@@ -170,13 +172,15 @@ public function unsubscribeFromAllChannels(ConnectionInterface $connection)
170172
* @param \Ratchet\ConnectionInterface $connection
171173
* @param string $channelName
172174
* @param stdClass $payload
173-
* @return void
175+
* @return PromiseInterface[bool]
174176
*/
175-
public function subscribeToChannel(ConnectionInterface $connection, string $channelName, stdClass $payload)
177+
public function subscribeToChannel(ConnectionInterface $connection, string $channelName, stdClass $payload): PromiseInterface
176178
{
177179
$channel = $this->findOrCreate($connection->app->id, $channelName);
178180

179-
$channel->subscribe($connection, $payload);
181+
return Helpers::createFulfilledPromise(
182+
$channel->subscribe($connection, $payload)
183+
);
180184
}
181185

182186
/**
@@ -185,35 +189,39 @@ public function subscribeToChannel(ConnectionInterface $connection, string $chan
185189
* @param \Ratchet\ConnectionInterface $connection
186190
* @param string $channelName
187191
* @param stdClass $payload
188-
* @return void
192+
* @return PromiseInterface[bool]
189193
*/
190-
public function unsubscribeFromChannel(ConnectionInterface $connection, string $channelName, stdClass $payload)
194+
public function unsubscribeFromChannel(ConnectionInterface $connection, string $channelName, stdClass $payload): PromiseInterface
191195
{
192196
$channel = $this->findOrCreate($connection->app->id, $channelName);
193197

194-
$channel->unsubscribe($connection, $payload);
198+
return Helpers::createFulfilledPromise(
199+
$channel->unsubscribe($connection, $payload)
200+
);
195201
}
196202

197203
/**
198-
* Subscribe the connection to a specific channel.
204+
* Subscribe the connection to a specific channel, returning
205+
* a promise containing the amount of connections.
199206
*
200207
* @param string|int $appId
201-
* @return void
208+
* @return PromiseInterface[int]
202209
*/
203-
public function subscribeToApp($appId)
210+
public function subscribeToApp($appId): PromiseInterface
204211
{
205-
//
212+
return Helpers::createFulfilledPromise(0);
206213
}
207214

208215
/**
209-
* Unsubscribe the connection from the channel.
216+
* Unsubscribe the connection from the channel, returning
217+
* a promise containing the amount of connections after decrement.
210218
*
211219
* @param string|int $appId
212-
* @return void
220+
* @return PromiseInterface[int]
213221
*/
214-
public function unsubscribeFromApp($appId)
222+
public function unsubscribeFromApp($appId): PromiseInterface
215223
{
216-
//
224+
return Helpers::createFulfilledPromise(0);
217225
}
218226

219227
/**
@@ -222,23 +230,21 @@ public function unsubscribeFromApp($appId)
222230
*
223231
* @param string|int $appId
224232
* @param string|null $channelName
225-
* @return \React\Promise\PromiseInterface
233+
* @return PromiseInterface[int]
226234
*/
227235
public function getLocalConnectionsCount($appId, string $channelName = null): PromiseInterface
228236
{
229237
return $this->getLocalChannels($appId)
230238
->then(function ($channels) use ($channelName) {
231-
return collect($channels)
232-
->when(! is_null($channelName), function ($collection) use ($channelName) {
233-
return $collection->filter(function (Channel $channel) use ($channelName) {
234-
return $channel->getName() === $channelName;
235-
});
236-
})
237-
->flatMap(function (Channel $channel) {
238-
return collect($channel->getConnections())->pluck('socketId');
239-
})
240-
->unique()
241-
->count();
239+
return collect($channels)->when(! is_null($channelName), function ($collection) use ($channelName) {
240+
return $collection->filter(function (Channel $channel) use ($channelName) {
241+
return $channel->getName() === $channelName;
242+
});
243+
})
244+
->flatMap(function (Channel $channel) {
245+
return collect($channel->getConnections())->pluck('socketId');
246+
})
247+
->unique()->count();
242248
});
243249
}
244250

@@ -248,7 +254,7 @@ public function getLocalConnectionsCount($appId, string $channelName = null): Pr
248254
*
249255
* @param string|int $appId
250256
* @param string|null $channelName
251-
* @return \React\Promise\PromiseInterface
257+
* @return PromiseInterface[int]
252258
*/
253259
public function getGlobalConnectionsCount($appId, string $channelName = null): PromiseInterface
254260
{
@@ -263,11 +269,11 @@ public function getGlobalConnectionsCount($appId, string $channelName = null): P
263269
* @param string $channel
264270
* @param stdClass $payload
265271
* @param string|null $serverId
266-
* @return bool
272+
* @return PromiseInterface[bool]
267273
*/
268-
public function broadcastAcrossServers($appId, ?string $socketId, string $channel, stdClass $payload, string $serverId = null)
274+
public function broadcastAcrossServers($appId, ?string $socketId, string $channel, stdClass $payload, string $serverId = null): PromiseInterface
269275
{
270-
return true;
276+
return Helpers::createFulfilledPromise(true);
271277
}
272278

273279
/**
@@ -277,12 +283,14 @@ public function broadcastAcrossServers($appId, ?string $socketId, string $channe
277283
* @param stdClass $user
278284
* @param string $channel
279285
* @param stdClass $payload
280-
* @return void
286+
* @return PromiseInterface[bool]
281287
*/
282-
public function userJoinedPresenceChannel(ConnectionInterface $connection, stdClass $user, string $channel, stdClass $payload)
288+
public function userJoinedPresenceChannel(ConnectionInterface $connection, stdClass $user, string $channel, stdClass $payload): PromiseInterface
283289
{
284290
$this->users["{$connection->app->id}:{$channel}"][$connection->socketId] = json_encode($user);
285291
$this->userSockets["{$connection->app->id}:{$channel}:{$user->user_id}"][] = $connection->socketId;
292+
293+
return Helpers::createFulfilledPromise(true);
286294
}
287295

288296
/**
@@ -292,9 +300,9 @@ public function userJoinedPresenceChannel(ConnectionInterface $connection, stdCl
292300
* @param stdClass $user
293301
* @param string $channel
294302
* @param stdClass $payload
295-
* @return void
303+
* @return PromiseInterface[bool]
296304
*/
297-
public function userLeftPresenceChannel(ConnectionInterface $connection, stdClass $user, string $channel)
305+
public function userLeftPresenceChannel(ConnectionInterface $connection, stdClass $user, string $channel): PromiseInterface
298306
{
299307
unset($this->users["{$connection->app->id}:{$channel}"][$connection->socketId]);
300308

@@ -310,6 +318,8 @@ public function userLeftPresenceChannel(ConnectionInterface $connection, stdClas
310318
unset($this->userSockets["{$connection->app->id}:{$channel}:{$user->user_id}"]);
311319
}
312320
}
321+
322+
return Helpers::createFulfilledPromise(true);
313323
}
314324

315325
/**
@@ -327,7 +337,7 @@ public function getChannelMembers($appId, string $channel): PromiseInterface
327337
return json_decode($user);
328338
})->unique('user_id')->toArray();
329339

330-
return new FulfilledPromise($members);
340+
return Helpers::createFulfilledPromise($members);
331341
}
332342

333343
/**
@@ -341,7 +351,7 @@ public function getChannelMember(ConnectionInterface $connection, string $channe
341351
{
342352
$member = $this->users["{$connection->app->id}:{$channel}"][$connection->socketId] ?? null;
343353

344-
return new FulfilledPromise($member);
354+
return Helpers::createFulfilledPromise($member);
345355
}
346356

347357
/**
@@ -362,7 +372,7 @@ public function getChannelsMembersCount($appId, array $channelNames): PromiseInt
362372
return $results;
363373
}, []);
364374

365-
return new FulfilledPromise($results);
375+
return Helpers::createFulfilledPromise($results);
366376
}
367377

368378
/**
@@ -375,7 +385,7 @@ public function getChannelsMembersCount($appId, array $channelNames): PromiseInt
375385
*/
376386
public function getMemberSockets($userId, $appId, $channelName): PromiseInterface
377387
{
378-
return new FulfilledPromise(
388+
return Helpers::createFulfilledPromise(
379389
$this->userSockets["{$appId}:{$channelName}:{$userId}"] ?? []
380390
);
381391
}
@@ -384,21 +394,21 @@ public function getMemberSockets($userId, $appId, $channelName): PromiseInterfac
384394
* Keep tracking the connections availability when they pong.
385395
*
386396
* @param \Ratchet\ConnectionInterface $connection
387-
* @return bool
397+
* @return PromiseInterface[bool]
388398
*/
389-
public function connectionPonged(ConnectionInterface $connection): bool
399+
public function connectionPonged(ConnectionInterface $connection): PromiseInterface
390400
{
391-
return true;
401+
return Helpers::createFulfilledPromise(true);
392402
}
393403

394404
/**
395405
* Remove the obsolete connections that didn't ponged in a while.
396406
*
397-
* @return bool
407+
* @return PromiseInterface[bool]
398408
*/
399-
public function removeObsoleteConnections(): bool
409+
public function removeObsoleteConnections(): PromiseInterface
400410
{
401-
return true;
411+
return Helpers::createFulfilledPromise(true);
402412
}
403413

404414
/**

0 commit comments

Comments
 (0)