lk404
lk404

Reputation: 334

Is it possible to store additional variables in a ratchet connection

this is my onMessage

public function onMessage(ConnectionInterface $from, $msg) {
    $tempMessage = json_decode($msg, TRUE);
    if ($tempMessage['type'] == 'online') {
        foreach ($this->clients as $client) {
            if ($client == $from) {
                echo "client " . $from->resourceId . "(" . $from->remoteAddress . ") is online\n";
            }
        }
    }

}

Is it possible to save values in this $client object for later reference?

i know it is possible to keep a array for this but it can get complicated as in the documentation im storing the clients in a SplObjectStorage

Upvotes: 4

Views: 1312

Answers (1)

Tofandel
Tofandel

Reputation: 3585

The Generic way

If you have a look at the php documentation for \SplObjectStorage you will see that you can add information to an object, so according to your code you can add the data like this

$this->clients[$from]->setInfo(['myData' => 'foo']);

And then retrieve it like this

$data   = $this->clients[$from]->getInfo();
var_dump($data); // $data = ['myData' => 'foo']

The Easy/Fast way

Disclaimer: this is only to set data in onOpen (eg: cookies), after that the connection is cloned everytime to be passed to onMessage making the original connection immutable, this is why I wouldn't recommend this solution to set data unrelated to the original connection, because it could lead to hard to debug bugs

Since the connection is a php class you are allowed to add properties to it as long as the property is not already defined as protected or private

In the source code of the client class (In \Ratchet\AbstractConnectionDecorator) you will find

public function __set($name, $value) {
    $this->wrappedConn->$name = $value;
}

public function __get($name) {
    return $this->wrappedConn->$name;
}

Meaning the class is just a wrapper for a \React\Socket\Connection which has no setter/getter.

So you can manipulate the properties like you would on an object

$client->myData = $data;
var_dump($client->myData);

The alternative way

Instead of storing your clients in an \SplObjectStorage store them in a keyed array and use spl_object_hash to generate the key

PS: This is already what's happening under the hood of SplObjectStorage so this is reinventing the wheel

/**
 * @var array[]
 */
protected $clients = [];

public function onOpen( ConnectionInterface $conn ) {
    $this->clients[spl_object_hash( $conn )] = [ 'connection' => $conn, 'myData' => "My data" ];
}

public function onMessage( ConnectionInterface $conn, $msg ) {
    $myData = $this->clients[spl_object_hash( $conn )]['myData'];
}

Upvotes: 7

Related Questions