Задать вопрос
Haotik
@Haotik
PHP мидл без фреймворков

Как идетифицировать сокет?

Пытаюсь реализовать следующую схему.
Поднят сервер на 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);
  • Вопрос задан
  • 90 просмотров
Подписаться 1 Простой 4 комментария
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы