Skip to content
This repository was archived by the owner on Mar 24, 2025. It is now read-only.

Commit 8ab430c

Browse files
authored
Merge pull request #17 from swooletw/develop
Develop
2 parents 7c8076d + 84be9cb commit 8ab430c

File tree

9 files changed

+213
-105
lines changed

9 files changed

+213
-105
lines changed

config/swoole_http.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@
3939

4040
/*
4141
|--------------------------------------------------------------------------
42-
| Laravel app will be cloned on every requset.
42+
| Laravel app will be cloned on every request.
4343
|--------------------------------------------------------------------------
4444
*/
4545
'sandbox_mode' => env('SWOOLE_SANDBOX_MODE', true),
4646

4747
/*
4848
|--------------------------------------------------------------------------
49-
| Console output will be transfered to response content if enabled.
49+
| Console output will be transferred to response content if enabled.
5050
|--------------------------------------------------------------------------
5151
*/
5252
'ob_output' => env('SWOOLE_OB_OUTPUT', true),

src/Websocket/Authenticatable.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
namespace SwooleTW\Http\Websocket;
4+
5+
use InvalidArgumentException;
6+
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
7+
8+
trait Authenticatable
9+
{
10+
/**
11+
* Login using current user.
12+
*/
13+
public function loginUsing(AuthenticatableContract $user)
14+
{
15+
return $this->loginUsingId($user->getAuthIdentifier());
16+
}
17+
18+
/**
19+
* Login using current userId.
20+
*/
21+
public function loginUsingId($userId)
22+
{
23+
return $this->join(static::USER_PREFIX . $userId);
24+
}
25+
26+
/**
27+
* Set multiple recepients' fds by users.
28+
*/
29+
public function toUser($users)
30+
{
31+
$users = is_object($users) ? func_get_args() : $users;
32+
33+
$userIds = array_map(function ($user) {
34+
$this->checkUser($user);
35+
return $user->getAuthIdentifier();
36+
}, $users);
37+
38+
return $this->toUserId($userIds);
39+
}
40+
41+
/**
42+
* Set multiple recepients' fds by userIds.
43+
*/
44+
public function toUserId($userIds)
45+
{
46+
$userIds = is_string($userIds) || is_integer($userIds) ? func_get_args() : $userIds;
47+
48+
foreach ($userIds as $userId) {
49+
$fds = $this->room->getClients(static::USER_PREFIX . $userId);
50+
$this->to($fds);
51+
}
52+
53+
return $this;
54+
}
55+
56+
/**
57+
* Check if user object implements AuthenticatableContract.
58+
*/
59+
protected function checkUser($user)
60+
{
61+
if (! $user instanceOf AuthenticatableContract) {
62+
throw new InvalidArgumentException('user object must implement ' . AuthenticatableContract::class);
63+
}
64+
}
65+
}

src/Websocket/Rooms/RedisRoom.php

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,28 +63,22 @@ public function getRedis()
6363
return $this->redis;
6464
}
6565

66-
public function add(int $fd, string $room)
66+
public function add(int $fd, $roomNames)
6767
{
68-
$this->addAll($fd, [$room]);
69-
}
68+
$roomNames = is_array($roomNames) ? $roomNames : [$roomNames];
7069

71-
public function addAll(int $fd, array $roomNames)
72-
{
7370
$this->addValue($fd, $roomNames, 'fds');
7471

7572
foreach ($roomNames as $room) {
7673
$this->addValue($room, [$fd], 'rooms');
7774
}
7875
}
7976

80-
public function delete(int $fd, string $room)
81-
{
82-
$this->deleteAll($fd, [$room]);
83-
}
84-
85-
public function deleteAll(int $fd, array $roomNames = [])
77+
public function delete(int $fd, $roomNames = [])
8678
{
79+
$roomNames = is_array($roomNames) ? $roomNames : [$roomNames];
8780
$roomNames = count($roomNames) ? $roomNames : $this->getRooms($fd);
81+
8882
$this->removeValue($fd, $roomNames, 'fds');
8983

9084
foreach ($roomNames as $room) {

src/Websocket/Rooms/RoomContract.php

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,20 @@ interface RoomContract
1010
public function prepare();
1111

1212
/**
13-
* Add a socket to a room.
13+
* Add multiple socket fds to a room.
1414
*
1515
* @int fd
16-
* @string room
16+
* @string|array rooms
1717
*/
18-
public function add(int $fd, string $room);
18+
public function add(int $fd, $rooms);
1919

2020
/**
21-
* Add a socket to multiple rooms.
21+
* Delete multiple socket fds from a room.
2222
*
2323
* @int fd
24-
* @array room
25-
*/
26-
public function addAll(int $fd, array $rooms);
27-
28-
/**
29-
* Delete a socket from a room.
30-
*
31-
* @int fd
32-
* @string room
33-
*/
34-
public function delete(int $fd, string $room);
35-
36-
/**
37-
* Delete a socket from all rooms.
38-
*
39-
* @int fd
40-
* @string room
24+
* @string|array rooms
4125
*/
42-
public function deleteAll(int $fd);
26+
public function delete(int $fd, $rooms);
4327

4428
/**
4529
* Get all sockets by a room key.

src/Websocket/Rooms/TableRoom.php

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,10 @@ public function prepare()
2424
$this->initFdsTable();
2525
}
2626

27-
public function add(int $fd, string $room)
28-
{
29-
$this->addAll($fd, [$room]);
30-
}
31-
32-
public function addAll(int $fd, array $roomNames)
27+
public function add(int $fd, $roomNames)
3328
{
3429
$rooms = $this->getRooms($fd);
30+
$roomNames = is_array($roomNames) ? $roomNames : [$roomNames];
3531

3632
foreach ($roomNames as $room) {
3733
$fds = $this->getClients($room);
@@ -49,14 +45,10 @@ public function addAll(int $fd, array $roomNames)
4945
$this->setRooms($fd, $rooms);
5046
}
5147

52-
public function delete(int $fd, string $room)
53-
{
54-
$this->deleteAll($fd, [$room]);
55-
}
56-
57-
public function deleteAll(int $fd, array $roomNames = [])
48+
public function delete(int $fd, $roomNames = [])
5849
{
5950
$allRooms = $this->getRooms($fd);
51+
$roomNames = is_array($roomNames) ? $roomNames : [$roomNames];
6052
$rooms = count($roomNames) ? $roomNames : $allRooms;
6153

6254
$removeRooms = [];

src/Websocket/Websocket.php

Lines changed: 23 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@
44

55
use InvalidArgumentException;
66
use Illuminate\Support\Facades\App;
7+
use SwooleTW\Http\Websocket\Authenticatable;
78
use Illuminate\Contracts\Container\Container;
89
use SwooleTW\Http\Websocket\Rooms\RoomContract;
910
use Illuminate\Contracts\Pipeline\Pipeline as PipelineContract;
1011

1112
class Websocket
1213
{
13-
const PUSH_ACTION = 'push';
14+
use Authenticatable;
1415

16+
const PUSH_ACTION = 'push';
1517
const EVENT_CONNECT = 'connect';
18+
const USER_PREFIX = 'uid_';
1619

1720
/**
1821
* Determine if to broadcast.
@@ -86,25 +89,15 @@ public function broadcast()
8689
return $this;
8790
}
8891

89-
/**
90-
* Set a recepient's fd or a room name.
91-
*
92-
* @param integer, string
93-
*/
94-
public function to($value)
95-
{
96-
$this->toAll([$value]);
97-
98-
return $this;
99-
}
100-
10192
/**
10293
* Set multiple recepients' fd or room names.
10394
*
104-
* @param array (fds or rooms)
95+
* @param integer, string, array
10596
*/
106-
public function toAll(array $values)
97+
public function to($values)
10798
{
99+
$values = is_string($values) || is_integer($values) ? func_get_args() : $values;
100+
108101
foreach ($values as $value) {
109102
if (! in_array($value, $this->to)) {
110103
$this->to[] = $value;
@@ -114,49 +107,29 @@ public function toAll(array $values)
114107
return $this;
115108
}
116109

117-
/**
118-
* Join sender to a room.
119-
*
120-
* @param string
121-
*/
122-
public function join(string $room)
123-
{
124-
$this->room->add($this->sender, $room);
125-
126-
return $this;
127-
}
128-
129110
/**
130111
* Join sender to multiple rooms.
131112
*
132-
* @param array
113+
* @param string, array
133114
*/
134-
public function joinAll(array $rooms)
115+
public function join($rooms)
135116
{
136-
$this->room->addAll($this->sender, $rooms);
137-
138-
return $this;
139-
}
117+
$rooms = is_string($rooms) || is_integer($rooms) ? func_get_args() : $rooms;
140118

141-
/**
142-
* Make sender leave a room.
143-
*
144-
* @param string
145-
*/
146-
public function leave(string $room)
147-
{
148-
$this->room->delete($this->sender, $room);
119+
$this->room->addAll($this->sender, $rooms);
149120

150121
return $this;
151122
}
152123

153124
/**
154125
* Make sender leave multiple rooms.
155126
*
156-
* @param array
127+
* @param string, array
157128
*/
158-
public function leaveAll(array $rooms = [])
129+
public function leave($rooms)
159130
{
131+
$rooms = is_string($rooms) || is_integer($rooms) ? func_get_args() : $rooms;
132+
160133
$this->room->deleteAll($this->sender, $rooms);
161134

162135
return $this;
@@ -322,7 +295,13 @@ protected function getFds()
322295
$rooms = array_diff($this->to, $fds);
323296

324297
foreach ($rooms as $room) {
325-
$fds = array_merge($fds, $this->room->getClients($room));
298+
$clients = $this->room->getClients($room);
299+
// rollback fd with wrong type back to fds array
300+
if (empty($clients) && is_numeric($room)) {
301+
$fds[] = $room;
302+
} else {
303+
$fds = array_merge($fds, $this->room->getClients($clients));
304+
}
326305
}
327306

328307
return array_values(array_unique($fds));

tests/Websocket/RedisRoomTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function testAddAll()
5151
->times(3);
5252
$redisRoom = $this->getRedisRoom($redis);
5353

54-
$redisRoom->addAll(1, ['foo', 'bar']);
54+
$redisRoom->add(1, ['foo', 'bar']);
5555
}
5656

5757
public function testAdd()
@@ -71,7 +71,7 @@ public function testDeleteAll()
7171
->times(3);
7272
$redisRoom = $this->getRedisRoom($redis);
7373

74-
$redisRoom->deleteAll(1, ['foo', 'bar']);
74+
$redisRoom->delete(1, ['foo', 'bar']);
7575
}
7676

7777
public function testDelete()

tests/Websocket/TableRoomTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function testSetValue()
5454

5555
public function testAddAll()
5656
{
57-
$this->tableRoom->addAll($key = 1, $values = ['foo', 'bar']);
57+
$this->tableRoom->add($key = 1, $values = ['foo', 'bar']);
5858

5959
$this->assertSame($values, $this->tableRoom->getValue($key, $table = 'fds'));
6060
$this->assertSame([$key], $this->tableRoom->getValue('foo', 'rooms'));
@@ -71,8 +71,8 @@ public function testAdd()
7171

7272
public function testDeleteAll()
7373
{
74-
$this->tableRoom->addAll($key = 1, $values = ['foo', 'bar']);
75-
$this->tableRoom->deleteAll($key);
74+
$this->tableRoom->add($key = 1, $values = ['foo', 'bar']);
75+
$this->tableRoom->delete($key);
7676

7777
$this->assertSame([], $this->tableRoom->getValue($key, $table = 'fds'));
7878
$this->assertSame([], $this->tableRoom->getValue('foo', 'rooms'));
@@ -81,7 +81,7 @@ public function testDeleteAll()
8181

8282
public function testDelete()
8383
{
84-
$this->tableRoom->addAll($key = 1, $values = ['foo', 'bar']);
84+
$this->tableRoom->add($key = 1, $values = ['foo', 'bar']);
8585
$this->tableRoom->delete($key, 'foo');
8686

8787
$this->assertSame(['bar'], $this->tableRoom->getValue($key, $table = 'fds'));
@@ -91,7 +91,7 @@ public function testDelete()
9191

9292
public function testGetRooms()
9393
{
94-
$this->tableRoom->addAll($key = 1, $values = ['foo', 'bar']);
94+
$this->tableRoom->add($key = 1, $values = ['foo', 'bar']);
9595

9696
$this->assertSame(
9797
$this->tableRoom->getValue($key, $table = 'fds'),

0 commit comments

Comments
 (0)