У меня есть сервер веб-сокетов, который содержит массив пользователей, которые содержат объекты импорта.
Я хочу отправлять обновления пользователю во время вызовов некоторых методов объекта импорта.
Я подумал, что для этого мне нужно будет передать ссылку на сервер и пользователя на мой объект импорта, однако, я боюсь, что из-за рекурсивной ссылки между моим пользователем и объектом импорта они никогда не перейдут кмусора и вызывает утечку памяти, когда я удаляю пользователя из моего списка пользователей, содержащихся в веб-сокете.
Я добавил на каждый объект __destruct
методы для проверки, когда мои объекты уничтожены.
class importServer extends WebSocketServer {
function __construct($addr, $port) { //set buffersize to 1M => 1048576
parent::__construct($addr, $port, 1048576);
$this->userClass = 'ImportUser';
}
protected function process ($user, $rawData) {
$this->send($user, "start processing data!");
if($data = json_decode($rawData, true)){
// check data length is as expected
if($this->check_data($data)){
if($workbooks = json_decode($data, true)){
foreach($workbooks as $workbook){
// Creating new import object for each worbook received
$obj = new import($workbook);
// check workbook data
$result = $obj->preprocessing();
if($result === true){
$this->send($user, "Preprocessing successfully completed!");
// User store import object for later import in DB
$user->imports[] = $obj;
}else{
$this->throw_error($user, $result);
}
Метод веб-сокета для сброса пользователя при отключении:
protected function disconnect($socket, $triggerClosed = true, $sockErrNo = null)
{
$disconnectedUser = $this->getUserBySocket($socket);
if ($disconnectedUser !== null) {
unset($this->users[$disconnectedUser->id]);
if (array_key_exists($disconnectedUser->id, $this->sockets)) {
unset($this->sockets[$disconnectedUser->id]);
}
if (!is_null($sockErrNo)) {
socket_clear_error($socket);
}
if ($triggerClosed) {
$this->stdout("Client disconnected. " . $disconnectedUser->socket);
$this->closed($disconnectedUser);
socket_close($disconnectedUser->socket);
} else {
$message = $this->frame('', $disconnectedUser, 'close');
@socket_write($disconnectedUser->socket, $message, strlen($message));
}
}
}
Метод уничтожения:
public function __destruct(){
echo __CLASS__ . " destruction";
}
Объект пользователя не разрушается при вызове unset, но когдановый пользователь подключается к веб-сокету, что касается объекта импорта, содержащегося в удаленном пользователе, он не разрушается даже при удалении рекурсивной ссылки.
console img
Я ожидал, что мои объекты импорта будут уничтожены при уничтожении объекта пользователя.