这是我的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
答案 0 :(得分:2)
想通了你应该编写一个单独的Repository类和一个连接类,并在Main类中使用它而不是在SplObjectStorage上存储客户端,你可以在存储库类中存储连接类的实例,这样你就可以存储其他类连接类上的数据,并使用Repository类来操作它们。
答案 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'];
}