Пытаюсь реализовать следующую схему.
Поднят сервер на php, к нему цепляются разные клиенты, которые сразу после соединения один раз отсылают свои идентификаторы и далее ждут.
по факту соединения октрытые сокеты добавляются в общий массив.
Сам сервер 5 секунд слушает изменения
После чего опрашивает бд и вытаскивает оттуда новые сообщения которые кладутся туда другим сервисом
Далее идет обход записей и должен сверяться идентификатор который передал сокет и идентификатор из бд если они совпадают то отсылается сообщение. И вот здесь у меня две проблемы.
1. Я не могу идентифицировать сокет. Она частично решена через создание объекта где хранится сам ресурс + к нему добивается идентификатор при получении
2. Обход сокетов в цикле и попытка запушить в них сообщение - не работает, по непонятной мне причине на каждой итерации массив с сокетами становится пустым
код
while (time() < $time) {
if (!empty($connects)) {
foreach ($connects as $value) {
$read[] = $value->SocketItem;
}
}else{
$read = $connects;
}
$read[]= $socket; //$socket - это процесс сервера
$write = $except = null;
stream_select($read, $write, $except, 5);
if (in_array($socket, $read)) {//есть новое соединение
//принимаем новое соединение и производим рукопожатие:
if (($connect = new SocketItem(stream_socket_accept($socket, -1))) && $info = handshake($connect->SocketItem)) {
$connect->SetLog($log);
$connects[] = $connect;//добавляем его в список необходимых для обработки
onOpen($connect, $info, $log);//вызываем пользовательский сценарий
}
unset($read[ array_search($socket, $read) ]);
}
if (time() > $bd_time) {
$bd_data = check_bd($db, $db_table);
$bd_time = set_bd_time();
}
$log->AddToLog("Сокеты",$connects);
foreach($connect as $key => $connect) {//обрабатываем все соединения
$data = fread($connect->SocketItem, 100000);
$connection_data = onMessage($connect, $data, $bd_data,$log);//вызываем пользовательский сценарий
if (empty($bd_data)) {
continue;
}
foreach ($bd_data as $rec_id => $record) {
$log->AddToLog('Проверка базы',[$key,$record]);
$msg = json_encode($record);
if ($rec_id == $connect->SocketID) {
$connect->send($msg);
}
}
if (!$data) { //соединение было закрыто
fclose($connect);
unset($connects[ array_search($connect->SocketItem, $connects) ]);
onClose($connect,$log);//вызываем пользовательский сценарий
continue;
}
}
}
fclose($socket);