Уничтожение объектов в php websocket - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть сервер веб-сокетов, который содержит массив пользователей, которые содержат объекты импорта.

Я хочу отправлять обновления пользователю во время вызовов некоторых методов объекта импорта.

Я подумал, что для этого мне нужно будет передать ссылку на сервер и пользователя на мой объект импорта, однако, я боюсь, что из-за рекурсивной ссылки между моим пользователем и объектом импорта они никогда не перейдут кмусора и вызывает утечку памяти, когда я удаляю пользователя из моего списка пользователей, содержащихся в веб-сокете.

Я добавил на каждый объект __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

Я ожидал, что мои объекты импорта будут уничтожены при уничтожении объекта пользователя.

...