Отправка данных с сервера на клиент?

У меня есть файл php-сервера и файл-клиент HTML, файл HTML отправляет запросы ajax на сервер для извлечения данных каждые 500 ms , хотя это работает, как ожидается, что приводит к высокому использованию памяти и процессора на клиентском устройстве.

PHP

 if(isset($_POST['id']) && $_POST['id'] != '' ) { $id = $_POST['id']; $select = $con->prepare("SELECT * FROM data WHERE id=?"); $select->bind_param('s', $id); $select->execute(); $result = $select->get_result(); while($row = $result->fetch_assoc()) { echo $row['column 1'] . "\t" . $row['column 2'] . "\n"; } } 

AJAX

 function send(){ var formdata = new FormData(), id = document.getElementById('id').value; formdata.append('id', id); var xhr = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); xhr.open('post', 'server.php', true); xhr.send(formdata); xhr.onreadystatechange = function(){ if(xhr.readyState == 4 && xhr.status == 200){ console.log(xhr.responseText); } } } setInterval(function(){send()}, 500); 

Я хотел бы найти альтернативное решение для ajax, вместо того, чтобы посылать многочисленные запросы на сервер и получать такие же данные большую часть времени, было бы намного более эффективно, если бы сервер мог взаимодействовать с клиентом при изменении или обновлении данных.

Я не могу использовать медикаменты PHP Socket или HttpRequest поскольку они не установлены на моем сервере хостинга, и я не уверен, работает ли позже. Единственный способ, которым я могу думать, – использовать SESSIONS .

в соответствии с этим сервером PHP хранит все сеансы пользователей в том же каталоге на сервере, поэтому может быть возможно изменить переменные сеансов для конкретного пользователя непосредственно в файле. однако проблема в том, что данные в этих файлах сериализованы, и я не уверен, как де-сериализовать данные и повторно сериализовать их, а затем сохранить новые данные!

Даже если мне удалось найти способ хранения обновлений в файле сеанса, мне все равно нужно использовать setInterval для прослушивания изменения переменной сеанса каждые 500ms хотя это не идеально, но было бы намного лучше, чем использование XMLHttpRequest с точки зрения памяти и Использование процессора.

Так что лучший способ сделать это? Любая помощь приветствуется.


ОБНОВИТЬ:

Я понял, что SESSION работает, потому что он может быть прочитан только сервером, а не клиентом, поэтому мне нужно отправить запрос ajax на сервер, чтобы получить переменные, которых я пытался избежать.

Я пробовал длительный опрос, но у меня было много проблем с ним, flush и ob_flush() не работают на моем сервере, и я не могу изменить настройки ini . При попытке бесконечного цикла я не могу заставить его сломаться при изменении данных:

 if(isset($_GET['size']) && $_GET['size'] != '') { $size = (int)$_GET['size']; $txt = "logs/logs.txt"; $newsize = (int)filesize($txt); while(true) { if($newsize !== $size) { $data = array( "size" => filesize($txt), "content" => file_get_contents($txt)); echo json_encode($data); break; } else{ $newsize = (int)filesize($txt); usleep(400000); } } } 

он продолжает logs.txt и дальше, даже если размер logs.txt ! как я могу заставить его ломать и эхо-данные по увеличению размера?

ОБНОВЛЕНИЕ 2:

оказалось, что php-кеш является файловым при вызове метода filesize() поэтому указанный цикл будет выполняться неограниченно, решение для этого – использовать clearstatcache() который очистит сохраненный кеш размера файла, позволяя циклу ломаться по размеру файла изменения.

Solutions Collecting From Web of "Отправка данных с сервера на клиент?"

Хорошо, после многих тестов и длительных исследований я пришел к выводу, что сервер PHP никогда не может взаимодействовать с указанным клиентом напрямую, если клиент не отправит запрос на сервер в первую очередь.

Единственное надежное решение, которое я нашел, – использовать бесконечный цикл, который будет только ломаться при изменении данных, это значительно уменьшит частоту аякс-запросов на сервер, следовательно, увеличит производительность и уменьшит использование памяти и процессора на устройстве клиента, вот как это получается:

PHP 1 (обрабатывает обновление данных или вставляет новые данные в базу данных):

 $process = $_POST['process']; $log = "/logs/logs.txt"; if($process == 'update'){ //execute mysqli update command and update table. $str = "Update on " . date('d/m/Y - H:i:s') . "\n";//add some text to the logs file (can be anything just to increase the logs.text size) file_put_content($log, $str, FILE_APPEND);//FILE_APPEND add string to the end of the file instead or replacing it's content } else if($process == 'insert'){ //execute mysqli insert command and add new data to table. $str = "Added new data on" . date('d/m/Y - H:i:s') . "\n"; file_put_content($log, $str, FILE_APPEND); } 

Вышеприведенный код будет вставлять / обновлять данные, создавать файл log.txt если он не существует, и добавлять к нему дополнительный текст по каждому запросу. log.txt будет использоваться позже в бесконечном цикле «ниже» и сломает цикл при изменении размера.

PHP 2 (обрабатывает запросы на чтение данных):

 if(isset($_POST['id']) && $_POST['id'] != '' && isset($_POST['size']) && $_POST['size'] != '') { $id = (string)$_POST['id']; $init_size = (int)$_POST['count']; $size = file_exists('logs/logs.txt') ? (int)filesize('logs/logs.txt') : 0;//$size is logs.txt size or 0 if logs.txt doesn't exist(not created yet). $select = $con->prepare("SELECT * FROM data WHERE id=?"); $select->bind_param('s', $id); while(true){ //while(true) will loop indefinitely because condition true is always met if($init_size !== $size){ $select->execute(); $result = $select->get_result(); while($row = $result->fetch_assoc()) { $data['rows'][] = array( "column 1" => $row['column 1'], "column 2" => $row['column 2'], ); } $data['size'] = $size; echo json_encode($data); break; //break the loop when condition ($init_size != $size) is met which indicates that database has been updated or new data has been added to it. } else{ clearstatcache(); //clears the chached filesize of log.txt $size = file_exists('logs/logs.txt') ? (int)filesize('logs/logs.txt') : 0; usleep(100000) //sleep for 100 ms } } } 

AJAX:

 var size = 0; //declares global variable size and set it's initial value to 0 function send(s){ var formdata = new FormData(), id = document.getElementById('id').value; formdata.append('id', id); formdata.append('size', s); var xhr = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); xhr.open('post', 'server.php', true); xhr.timeout = 25000; //set timeout on xmlhttprequest to 25 sec, some servers has short execution tiemout, in my case it's 27 sec so i set the value to 25 sec. xhr.send(formdata); xhr.onreadystatechange = function(){ if(xhr.readyState == 4 && xhr.status == 200){ var data = JSON.parse(xhr.responseText); size = data.size; console.log(data.rows); setTimeout(function(){send(size)}, 100); //re-initiate the request after receiving data } } xhr.ontimeout = function(){ xhr.abort(); //abort the timed out xmlhttp request setTimeout(function(){send(size)}, 100); } send(size); 

Это не идеальное решение, но оно уменьшило мои запросы xmlhttp от 2 / сек до 1,55 секунд, надеясь, что кто-то сможет придумать лучшее решение.

Раньше у нас были возможности использовать сокеты в браузерах, мы использовали Long-опрос. Основная идея заключается в том, что вместо того, чтобы браузер выполнял запросы через регулярные промежутки времени, браузер отправляет запрос на сервер, но сервер не будет реагировать, пока не появится что-то стоящее, чтобы поделиться с ним в браузере. Это означает, что запрос может быть оставлен открытым в течение 10 мс или в течение нескольких часов.

После того, как сервер что-то ответит, именно задание браузера должно сделать новый запрос ajax. Таким образом, всегда есть линия, открытая для сервера.

См. Этот вопрос для получения дополнительной информации.

Отвечая на часть вашего вопроса о прямом редактировании сеанса …

Чтобы напрямую манипулировать сеансом пользователя, я предполагаю, что вы знаете и можете отслеживать идентификатор сеанса пользователя (возможно, в вашей базе данных при входе).

Когда вам нужно отредактировать сеанс пользователя непосредственно на сервере:

  1. Получить последнюю известную сессию пользователя из базы данных.
  2. Вызовите session_close() чтобы закрыть текущий сеанс (если он есть).
  3. Вызовите `session_name ($ sessionId) 'с идентификатором сеанса.
  4. Вызовите session_open() чтобы открыть этот сеанс. $_SESSION должен быть заполнен данными сеанса. Вам не нужно ничего не разбирать.
  5. Внесите свои изменения в сеанс.
  6. Вызовите session_close() для повторной инициализации данных.

Кроме того, вы можете напрямую открыть файл сеанса, выполнить его unserialize() , отредактировать данные и повторно serialize() вручную.

Вы можете создать ajax-запрос для php-скрипта, который будет возвращать данные только в случае новых данных. Пока нет новых данных, скрипт продолжает работать в цикле до тех пор, пока он не появится.

Я думаю, что сегодня для этого вопроса нужно использовать Websocket, чтобы прочитать об этом. без запроса сервер вы можете получить данные, если что-то изменит его на сервер

см. ссылку