Huzzah
@Huzzah
web-developer

Как отправить push-уведомление (Nginx, PHP)?

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

если я правильно понимаю, то задача состоит дальше в том, чтобы создать под-процесс и открыть канал (nginx push module), чтобы браузер мог прослушивать сообщения на данном канале. по завершении всех операций в под-процессе в канал необходимо отправить сообщение о результате.

как создать/открыть под-процесс в PHP/Windows и закрыть его, утилизировать? Как правильно настроить nginx канал?
  • Вопрос задан
  • 4332 просмотра
Пригласить эксперта
Ответы на вопрос 3
fornit1917
@fornit1917
Гуглите по словам Comet, Long Polling.

Хотя в вашем случае даже Short Polling наверное подойдет, без всяких там Comet. То есть вы загружаете фотки и все. На сервере они отдельно обрабатываются в фоне (для этого можно использовать менеджер очередей, либо просто в бд складываете задачи и скриптом, запускаемым по расписанию, их разгребаете). Когда обработка фоток закончится - сообщаете об этом базе данных.
В это время браузер периодически будет аяксом у сервера спрашивать - закончилась ли обработка
Ответ написан
Комментировать
Huzzah
@Huzzah Автор вопроса
web-developer
@fornit1917

- мне нужно после загрузки и обработки изображений перенаправить пользователя на страницу редактирования. Т. е. мне нужно знать, что все фотки из панели загрузки либо обработались удачно, либо обработались неудачно (суть не в перехвате исключений).
- понятно про БД.
- не ясно про фоновый режим. что такое обработчик очередей я понимаю, но не пробовал использовать. читал про redis, activemq, zeromq, rabbitmq. нужен обработчик очередей, который можно использовать под Windows (Server 2008) + простой пример его использования.
- на данный момент идея есть такая:

$app->post('/photos-upload', function() use ($app, $dbConn) { 
    // проверили все что нам нужно
    $app->performAsyncPost('http://localhost:8090/mx/api/photos-process', array(
        // отправляем всякие данные
        'args' => 'data'
    ));
}
$app->post('/photos-process', function() use ($app, $dbConn) { 
    // отправляем что-то вроде curl http://localhost/pub?id=ch1 -d "Pending"
    // делаем нужные нам операции
    // отправляем что-то вроде curl http://localhost/pub?id=ch1 -d "Done"
}

public function performAsyncPost($url, array $params) {
    foreach($params as $key => &$val) {
        if(is_array($val)) $val = implode(',', $val);
        $post_params[] = $key.'='.urlencode($val);  
    }
            
    $post_string = implode('&', $post_params);
    $parts = parse_url($url);

    $fp = fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80, $errno, $errstr, 30);

    $out = "POST ".$parts['path']." HTTP/1.1\r\n";
    $out.= "Host: ".$parts['host']."\r\n";
    $out.= "Content-Type: application/x-www-form-urlencoded\r\n";
    $out.= "Content-Length: ".strlen($post_string)."\r\n";
    $out.= "Connection: Close\r\n\r\n";
    if(isset($post_string)) $out.= $post_string;
    fwrite($fp, $out);
    fclose($fp);
}


на клиентской стороне опрашивать канал-файл
Ответ написан
Комментировать
Keksinautin
@Keksinautin
Software Engineer
Если я правильно понял, задача состоит в том, чтобы асинхронно выгрузить на сервер 20 картинок (которые там должны быть обработаны после загрузки) и, само собой, узнать о том, как все это прошло.
Во первых у меня большие сомнения насчет 20 одновременных соединений с сервером. Браузеры ограничивают количество одновременных соединений к одному серверу. Может быть 20 одновременно и не получится, надо гуглить для каждого браузера эти значения.
Во вторых я бы использовал для этого такую схему:
1. Nginx HttpUploadModule загружает файл и только после этого проксирует запрос дальше, серверу который будут выполнять обработку файла. В нашем случае PHP.
2. А HttpUploadProgressModule поможет нам отслеживать процесс загрузки файла.
3. Соответственно, когда собрали ответы обо всех успешных 20 загрузках на фронт-енде уже может делать что хотим.
Ответ написан
Ваш ответ на вопрос

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

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