是否可以在棘轮连接中存储其他变量

时间:2015-03-24 12:49:01

标签: php websocket ratchet

这是我的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";
            }
        }
    }

}

是否可以在此$ client对象中保存值以供以后参考?

我知道可以为此保留一个数组,但它可能会变得复杂 如在文档中我将客户端存储在SplObjectStorage

2 个答案:

答案 0 :(得分:2)

想通了你应该编写一个单独的Repository类和一个连接类,并在Main类中使用它而不是在SplObjectStorage上存储客户端,你可以在存储库类中存储连接类的实例,这样你就可以存储其他类连接类上的数据,并使用Repository类来操作它们。

follow this tutorial

答案 1 :(得分:0)

通用方式

如果您查看\SplObjectStorage的{​​{3}},您会发现您可以向对象添加信息,因此根据您的代码,您可以像这样添加数据

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

然后像这样检索它

$this->clients->rewind();
while($this->clients->valid()) {
    $client = $this->clients->current();
    $data   = $this->clients->getInfo();
    var_dump($data); // $data = ['myData' => 'foo']
    $this->clients->next();
}

简便/快捷方式

免责声明: :此操作仅用于在onOpen中设置数据(例如cookie),之后每次克隆该连接以将其传递给onMessage时,原始连接将保持不变,这就是为什么我不建议使用此解决方案来设置与原始连接无关的数据的原因,因为它可能导致难以调试的错误

  

由于连接是php类,因此您可以添加属性   只要该属性尚未被定义为受保护或   私人

     

在客户端类的源代码中(在   \Ratchet\AbstractConnectionDecorator),您会发现

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

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

表示该类只是\React\Socket\Connection的包装   没有设置器/获取器。

因此您可以像对待对象一样操作属性

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

替代方式

与其将客户存储在\SplObjectStorage中,不如将它们存储在键控数组中,并使用spl_object_hash来生成密钥

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

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

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