1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Tidal\WampWatch; |
4
|
|
|
|
5
|
|
|
/* |
6
|
|
|
* Copyright 2015 Timo. |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please view the LICENSE file |
9
|
|
|
* that was distributed with this source code. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
use Evenement\EventEmitterInterface; |
13
|
|
|
use Tidal\WampWatch\ClientSessionInterface as ClientSession; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Description of SessionMonitor. |
17
|
|
|
* |
18
|
|
|
* @author Timo |
19
|
|
|
*/ |
20
|
|
|
class SessionMonitor implements MonitorInterface, EventEmitterInterface |
21
|
|
|
{ |
22
|
|
|
use |
23
|
|
|
MonitorTrait { |
24
|
|
|
start as doStart; |
25
|
|
|
stop as doStop; |
26
|
|
|
} |
27
|
|
|
|
28
|
|
|
const SESSION_JOIN_TOPIC = 'wamp.session.on_join'; |
29
|
|
|
const SESSION_LEAVE_TOPIC = 'wamp.session.on_leave'; |
30
|
|
|
const SESSION_COUNT_TOPIC = 'wamp.session.count'; |
31
|
|
|
const SESSION_LIST_TOPIC = 'wamp.session.list'; |
32
|
|
|
const SESSION_INFO_TOPIC = 'wamp.session.get'; |
33
|
|
|
|
34
|
|
|
|
35
|
|
|
protected $sessionIds = []; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Constructor. |
39
|
|
|
* |
40
|
|
|
* @param ClientSession $session |
41
|
|
|
*/ |
42
|
|
|
public function __construct(ClientSession $session) |
43
|
|
|
{ |
44
|
|
|
$this->setClientSession($session); |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Start the monitor. |
49
|
|
|
* |
50
|
|
|
* @return bool |
51
|
|
|
*/ |
52
|
|
|
public function start() |
53
|
|
|
{ |
54
|
|
|
$this->once('list', function () { |
55
|
|
|
$this->doStart(); |
56
|
|
|
}); |
57
|
|
|
$this->startSubscriptions(); |
58
|
|
|
$this->retrieveSessionIds(); |
59
|
|
|
|
60
|
|
|
return true; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Stop the monitor. |
65
|
|
|
* Returns boolean wether the monitor could be started. |
66
|
|
|
* |
67
|
|
|
* @return bool |
68
|
|
|
*/ |
69
|
|
|
public function stop() |
70
|
|
|
{ |
71
|
|
|
$this->stopSubscriptions(); |
72
|
|
|
$this->doStop(); |
73
|
|
|
|
74
|
|
|
return true; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Retrieves the session-info for given sessionId |
79
|
|
|
* and populates it in via given callback. |
80
|
|
|
* |
81
|
|
|
* @param $sessionId |
82
|
|
|
* @param callable $callback |
83
|
|
|
* |
84
|
|
|
* @return mixed |
85
|
|
|
*/ |
86
|
|
|
public function getSessionInfo($sessionId, callable $callback) |
87
|
|
|
{ |
88
|
|
|
return $this->session->call(self::SESSION_INFO_TOPIC, [$sessionId])->then( |
89
|
|
|
function ($res) use ($callback) { |
90
|
|
|
$this->emit('info', [$res[0]]); |
91
|
|
|
$callback($res[0]); |
92
|
|
|
}, |
93
|
|
|
function ($error) { |
94
|
|
|
$this->emit('error', [$error]); |
95
|
|
|
} |
96
|
|
|
); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Retrieves the Ids of the sessions currently |
101
|
|
|
* registered on the wamp-router in the monitor's realm |
102
|
|
|
* and populates the data via given callback,. |
103
|
|
|
* |
104
|
|
|
* @param callable $callback |
105
|
|
|
* |
106
|
|
|
* @return mixed |
107
|
|
|
*/ |
108
|
|
|
public function getSessionIds(callable $callback) |
109
|
|
|
{ |
110
|
|
|
if (!count($this->sessionIds)) { |
111
|
|
|
$this->retrieveSessionIds($callback); |
112
|
|
|
} else { |
113
|
|
|
$callback($this->sessionIds); |
114
|
|
|
} |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* Initializes the subscription to the meta-events. |
119
|
|
|
*/ |
120
|
|
|
protected function startSubscriptions() |
121
|
|
|
{ |
122
|
|
View Code Duplication |
$this->session->subscribe(self::SESSION_JOIN_TOPIC, function ($res) { |
|
|
|
|
123
|
|
|
$sessionInfo = $res[0]; |
124
|
|
|
$sessionId = $sessionInfo->session; |
125
|
|
|
if ((array_search($sessionId, $this->sessionIds)) === false) { |
126
|
|
|
$this->sessionIds[] = $sessionId; |
127
|
|
|
$this->emit('join', [$sessionInfo]); |
128
|
|
|
} |
129
|
|
|
}); |
130
|
|
View Code Duplication |
$this->session->subscribe(self::SESSION_LEAVE_TOPIC, function ($res) { |
|
|
|
|
131
|
|
|
// @bug : wamp.session.on_leave is bugged as of crossbar.io 0.11.0 |
132
|
|
|
// will provide sessionID when Browser closes/reloads, |
133
|
|
|
// but not when calling connection.close(); |
134
|
|
|
$sessionId = $res[0]; |
135
|
|
|
if (($key = array_search($sessionId, $this->sessionIds)) !== false) { |
136
|
|
|
unset($this->sessionIds[$key]); |
137
|
|
|
$this->emit('leave', [$sessionId]); |
138
|
|
|
} |
139
|
|
|
}); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* Unsubscribes from the meta-events. |
144
|
|
|
*/ |
145
|
|
|
protected function stopSubscriptions() |
146
|
|
|
{ |
147
|
|
|
Util::unsubscribe($this->session, self::SESSION_JOIN_TOPIC); |
|
|
|
|
148
|
|
|
Util::unsubscribe($this->session, self::SESSION_LEAVE_TOPIC); |
|
|
|
|
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Retrieves the list of current sessionIds on the router. |
153
|
|
|
* |
154
|
|
|
* @param callable|null $callback |
155
|
|
|
*/ |
156
|
|
|
protected function retrieveSessionIds(callable $callback = null) |
157
|
|
|
{ |
158
|
|
|
$this->session->call(self::SESSION_LIST_TOPIC, [])->then( |
159
|
|
|
function ($res) use ($callback) { |
160
|
|
|
// remove our own sessionID from the tracked sessions |
161
|
|
|
$sessionIds = $this->removeOwnSessionId($res[0]); |
162
|
|
|
$this->setList($sessionIds); |
163
|
|
|
$this->emit('list', [$this->getList()]); |
164
|
|
|
if ($callback !== null) { |
165
|
|
|
$callback($this->sessionIds); |
166
|
|
|
} |
167
|
|
|
}, |
168
|
|
|
function ($error) { |
169
|
|
|
$this->emit('error', [$error]); |
170
|
|
|
} |
171
|
|
|
); |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
protected function setList($list) |
175
|
|
|
{ |
176
|
|
|
$this->sessionIds = $list; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
protected function getList() |
180
|
|
|
{ |
181
|
|
|
return $this->sessionIds; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* remove the sessionID of the Monitor from the list. |
186
|
|
|
* |
187
|
|
|
* @param array $sessionsIds |
188
|
|
|
* |
189
|
|
|
* @return mixed |
190
|
|
|
*/ |
191
|
|
|
protected function removeOwnSessionId(array $sessionsIds) |
192
|
|
|
{ |
193
|
|
|
$key = array_search($this->session->getSessionId(), $sessionsIds); |
194
|
|
|
if ($key >= 0) { |
195
|
|
|
unset($sessionsIds[$key]); |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
return $sessionsIds; |
199
|
|
|
} |
200
|
|
|
} |
201
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.