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

omqzjyyz  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(131)

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

t5zmwmid

t5zmwmid1#

通用方式

如果你看一下\SplObjectStoragephp documentation,你会发现你可以向一个对象添加信息,所以根据你的代码你可以像这样添加数据

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

然后像这样取回它

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

简单/快速的方式

***免责声明:***这仅用于在onOpen中设置数据(例如:cookie),之后每次都克隆连接以传递给onMessage,从而使原始连接不可变,这就是为什么我不推荐使用此解决方案来设置与原始连接无关的数据,因为这可能会导致难以调试的错误

因为连接是一个php类,所以只要属性没有被定义为protected或private,就可以添加属性
在客户端类(In \Ratchet\AbstractConnectionDecorator)的源代码中,您将找到

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

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

这意味着类只是\React\Socket\Connection的 Package ,它没有setter/getter。
因此,您可以像处理对象一样处理属性

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

另一种方式

不是将客户端存储在\SplObjectStorage中,而是将它们存储在键控数组中,并使用spl_object_hash生成密钥

  • PS:这是SplObjectStorage的幕后工作,因此这是在重新发明轮子 *
/**
 * @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'];
}

相关问题