Мне пришлось реализовать связь между приложением, написанным на c ++, и веб-сервером, написанным на PHP.
Основная идея состояла в том, чтобы создать сокет с приложением c ++, связать его и прослушать соединение PHP с ним.
Затем PHP отправит сообщение через TCP с запросом данных, а c ++ отправит ответ. Запрос с одним заголовком, ответ с одной строкой (JSON).
Все идет нормально.
Это код, который я использовал для стороны PHP:
<?php
error_reporting(E_ALL);
$service_port = 8080;
$address = 'localhost';$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
}
echo "Attempting to connect to '$address' on port '$service_port'...";
$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
}$in = "request1";
$out = '';
socket_write($socket, $in, strlen($in));
$buf = 'This is my buffer.';
if (false !== ($bytes = socket_recv($socket, $buf, 2048, MSG_WAITALL))) {
echo "Read $bytes bytes from socket_recv(). Closing socket...";
} else {
echo "socket_recv() failed; reason: " . socket_strerror(socket_last_error($socket)) . "\n";
}
socket_close($socket);
echo $buf . "\n";
//elaborate the $buf
?>
Теперь я хотел бы также реализовать автоматическое обновление данных, при этом c ++ (на стороне сервера) отправляет данные, а на стороне PHP (на стороне клиента) их собирает.
Обновление данных должно быть сделано каждую минуту.
К сожалению, у меня нет большого опыта в веб-разработке, поэтому я прошу несколько советов по этому поводу.
Самым простым, что я мог сделать, было зацикливание кода PHP до получения известного сообщения. Проблема, с которой я столкнулся, заключается в том, что я не получаю данные до тех пор, пока цикл не закончится и скрипт PHP не закончится.
Чтобы преодолеть проблему, я попытался установить неблокирующую сторону сокета PHP
заменив в socket_recv параметр MSG_WAITALL на MSG_DONTWAIT, но ничего не изменилось. Затем я попытался выйти из сценария PHP, но это не удалось сделать, поскольку мне нужно было циклически повторять его, чтобы получать данные каждую секунду.
Кроме того, у меня возникает другая проблема: во время циклов на сервере apache, на котором работает PHP, возникает ошибка 503, сервер недоступен.
Я не знаю, почему это происходит, возможно, буфер принятых сообщений переполнен, или скрипт занимает слишком много ресурсов.
Из-за недостатка опыта не могу понять почему.
Я знаю, что есть хорошие библиотеки для выполнения того, что мне нужно, но я работаю на встроенном компьютере, поэтому я ограничен в работе с базовыми библиотеками.
Как мне получить PHP на сервере Apache для получения синхронизированных данных из приложения c ++? Что я пропускаю?
Заранее большое спасибо за вашу помощь.
Изменить: удаленный риторический вопрос.
Использование php для получения данных из другого процесса через tcp / ip потребует немного больше усилий по сравнению с отправкой данных из скрипта php, выполняемого через apache, в другой процесс с использованием сокетов tcp / ip.
Ваш php-скрипт должен быть запущен вне apache и потребует бесконечного цикла, который непрерывно прослушивает данный порт для чтения входных данных. следующий пост обрисовывает в общих чертах то, что я полагаю, что Вы после.
РЕДАКТИРОВАТЬ
Для отображения результатов на веб-странице вы можете использовать хранилище данных в памяти, такое как Redis. Приложение сервера php обновит структуру данных в redis, затем при загрузке веб-страницы можно будет извлечь последнее значение из redis и отобразить его на экране, однако для этого потребуется обновление страницы.
Если вам требуется немедленное обновление данных после получения без обратной передачи с сервера, для этого потребуется некоторый JavaScript. Когда пользователь загружает страницу, вы инициализируете соединение веб-сокета с сервером веб-сокета (люди обычно используют для реализации этого node.js и socket.io, но вы можете кодировать сервер веб-сокета во всем, что поддерживает технологию). Сервер веб-сокетов будет подписан на канал Redis, который при обновлении будет отправлять новые значения всем подключенным клиентам. Я полагаю, что это можно сделать и без повторного редактирования, в зависимости от ваших требований. Программа для сервера websocket также может быть сервером, который принимает информацию из вашей программы на c ++, используя отдельный поток. Когда данные поступают из программы на С ++, вы можете отправить их напрямую клиентам, подключенным через веб-сокет.
Не изобретай велосипед. Используйте веб-розетки. Он предназначен для этой асинхронной связи, и вы можете отлично передавать JSON через него.
Существуют библиотеки для C ++ и PHP, поэтому это должно быть довольно просто.