是否可以在棘轮连接中存储附加变量

lk4*_*404 3 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";
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

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

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

Tof*_*del 6

通用方式

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

$this->clients[$from]->setInfo(['myData' => 'foo']);
Run Code Online (Sandbox Code Playgroud)

然后像这样检索它

$data   = $this->clients[$from]->getInfo();
var_dump($data); // $data = ['myData' => 'foo']
Run Code Online (Sandbox Code Playgroud)

简单/快速的方法

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

由于连接是一个 php 类,只要该属性尚未定义为受保护或私有,您就可以向其添加属性

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

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

public function __get($name) {
    return $this->wrappedConn->$name;
}
Run Code Online (Sandbox Code Playgroud)

这意味着该类只是一个\React\Socket\Connection 没有 setter/getter 的包装器。

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

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

public function __get($name) {
    return $this->wrappedConn->$name;
}
Run Code Online (Sandbox Code Playgroud)

另一种方式

不要将您的客户端存储\SplObjectStorage在密钥数组中并用于spl_object_hash生成密钥

PS:这已经是 SplObjectStorage 底层发生的事情了,所以这是重新发明轮子

$client->myData = $data;
var_dump($client->myData);
Run Code Online (Sandbox Code Playgroud)