gpt4 book ai didi

PHP/Ratchet websocket - while 循环问题

转载 作者:行者123 更新时间:2023-12-04 16:13:05 25 4
gpt4 key购买 nike

我有一个使用 PHP 和 Ratchet 库的非常简单的 websocket。
当用户打开特定页面时,它会将用户 ID 发送到我的套接字,并且它应该更新该用户的状态(目前我只是在控制台中记录它),如下所示:

<input type="hidden" value="'.$account_id.'" id="account_id">
<input type="hidden" value="trial" id="request_type">
<script>
$(document).ready(function(){
var conn = new WebSocket('ws://127.0.0.1:8080');

conn.onopen = function(e){
console.log("Connection Opened!");
var account_id = $("#account_id").val();
var request_type = $("#request_type").val();
var data = {account_id: account_id, request_type: request_type};
conn.send(JSON.stringify(data));
}
conn.onclose = function(e){
console.log("Connection Closed!");
}
conn.onmessage = function(e) {
var data = JSON.parse(e.data);
console.log(data);
};
conn.onerror = function(e){
var data = JSON.parse(e.data);
console.log(data);
}
})
</script>
那么我的socket脚本如下:
set_time_limit(0);

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
require dirname(__DIR__) . '../vendor/autoload.php';

class socket implements MessageComponentInterface{
protected $clients;

public function __construct(){
$this->clients = new \SplObjectStorage;
echo 'Server Started.'.PHP_EOL;
}

public function onOpen(ConnectionInterface $socket){
$this->clients->attach($socket);
echo 'New connection '.$socket->resourceId.'!'.PHP_EOL;
}
public function onClose(ConnectionInterface $socket) {
$this->clients->detach($socket);
echo 'Connection '.$socket->resourceId.' has disconnected'.PHP_EOL;
}
public function onError(ConnectionInterface $socket, \Exception $e) {
echo 'An error has occurred: '.$e->getMessage().'!'.PHP_EOL;
$socket->close();
}
public function onMessage(ConnectionInterface $from, $json){
echo 'Connection '.$from->resourceId.' sent '.$json.PHP_EOL;
$data = json_decode($json, true);
$account_id = $data['account_id'];
$request_type = $data['request_type'];

try {
$conn = new PDO("mysql:host=".$db_host.";port:".$db_port.";dbname=".$db_name."", $db_user, $db_pass);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
echo $e->getMessage();
}

foreach ($this->clients as $client) {
if ($from->resourceId == $client->resourceId) {
if($request_type == 'trial'){
// while(true){
$response_array= [];
$stmt = $conn->prepare("SELECT * FROM table WHERE account_id=:account_id AND last_status_change=now()");
$stmt->bindParam(':account_id', $account_id);
$stmt->execute();
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
foreach($stmt->fetchAll() as $key=>$value) {
$response_array[$key] = $value;
}
if(!empty($response_array)){
foreach($response_array as $item){
$status = $item['status'];
}
$response = array(
'account_id' => $account_id,
'status' => $status
);
var_dump($response);
$client->send(json_encode($response));
}
// sleep(5);
// }
}
}
}
}
}

$server = IoServer::factory(
new HttpServer(
new WsServer(
new socket()
)
),
8080
);
$server->run();
就目前而言,它按预期工作,但仅当页面加载时状态发生变化时才提供当前状态,我将在控制台中看到状态,只要我取消评论 while()循环实际继续检查更新状态,我的套接字将执行 var_dump()当状态发生变化但客户端没有记录任何内容时,命令行中的结果。
我是 websockets 的新手,我一直在通过在 JS 中发送 fetch() 的间隔来进行长轮询。到一个获得最新数据库结果的 PHP 脚本,但它不是很有效,并且当大量客户端处于事件状态并不断向文件发出请求时会导致问题,这反过来又减慢了数据库的速度。所以我不确定为什么 while()循环正在像这样影响它,或者如果我什至以正确的方式进行处理。

最佳答案

while 循环不是它的工作原理。它会阻塞东西并无限地和不必要地消耗资源。
您要的是 addPeriodicTimer() .
定期检查需要更新的客户。
添加到您的 bootstrap 中,如下所示:

$reactEventLoop->addPeriodicTimer(5, function() use $messageHandler, $server {
// Fetch all changed clients at once and update their status
$clientsToUpdate = getUpdatedClients($server->app->clients);
foreach ($clientsToUpdate as $client) {
$client->send(json_encode($response));
}
});
这比任何其他方法都轻得多,因为您可以
  • 使用单个准备好的数据库查询获取 N 个客户端状态
  • 仅定期更新更改的客户端
  • 不要将您的应用置于阻塞状态

  • Stackoverflow 上的其他资源将帮助您找到正确的位置:
    How do I access the ratchet php periodic loop and client sending inside app?
    Periodically sending messages to clients in Ratchet

    关于PHP/Ratchet websocket - while 循环问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65741189/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com