Bonjour,

J'ai une application avec un client (en JSP + Ajax) et un serveur PHP.

Le client envoi un numéro de client au serveur php (jusque là, rien de bien compliqué).
Ensuite, le serveur récupère en base les info du client puis réalise une fusion publipostage avec LibreOffice.

Le lien du PDF est retourné au client.

Un problème, c'est que la fusion publipostage n'est possible que pour un utilisateur à la fois. J'ai donc une variable en base de donnée qui sert de verrou.

Mais là où je suis perdu, c'est qu'au bout d'un certain temps la requête Ajax part en timeout. En effet, le nombre de document produit par la fusion publipostage + conversion en PDF est grandissant.

Je me suis donc orienté vers une barre de progression (mais sans barre de progression car je ne sais pas calculer le temps restant). Je souhaites envoyer toutes les 5 ou 10 sec une requête Ajax pour vérifier l'état du traitement et s'il est terminé, récupérer le lien du PDF.

Malheureusement, je comptais sur le mécanisme de session. Si le numéro de client est en session, je vérifie si une variable de session 'finish' contient quelque chose puis je retourne le message (lien du PDF ou message d'erreur) au client.

Mais ça ne fonctionne pas.

Comment dois-je procéder ?

Mon code PHP :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// début de session : un identifiant unique est créé pour chaque utilisateur
session_start();
 
header('Access-Control-Allow-Origin: *');
header('Content-Type: text/html; charset=UTF-8');
header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1.
header('Pragma: no-cache'); // HTTP 1.0.
header('Expires: 0'); // Proxies.
 
date_default_timezone_set('Europe/Paris');
 
require_once 'config_inc.php';
require_once 'database_api.php';
 
// définit un nouveau logger avec comme granularité LogLevel <voir PATH_LOGS/Logger.php>
$logger = new Logger(PATH_LOGS, LogLevel::DEBUG);
 
$logger->log(LogLevel::DEBUG, "***********");
if ($_SESSION['num_cli'] != '') {
    // si le traitement est terminé, on renvoi
    if (isset($_SESSION['finish'])) {
        session_unset();
        session_destroy();
        $logger->log(LogLevel::DEBUG, "FIN DE SESSION");
        exit($_SESSION['finish']);
    } else {
        $logger->log(LogLevel::DEBUG, "En cours de traitement");
        ob_flush();
        flush();
    }
} else {
 
    // ignore les déconnections clientes
    ignore_user_abort(true);
    // temps limite de 120 secondes
    set_time_limit(120);
    $_SESSION['num_cli'] = $_REQUEST["num_cli"];
 
    ob_flush();
    flush();
 
    $logger->log(LogLevel::DEBUG, 'Execution du long script ...');
    sleep(60);
merci

EDIT: J'ai pensé lancer mon traitement de fusion publipostage en tant que programme externe mais je ne vois pas comment récupérer le retour. Peut être que je dois gérer le verrou dans l'index pour être sûr que mon programme n'est lancé qu'une seule fois puis écrire dans un fichier le retour.
A chaque fois qu'un client lance une requête, je regarde le fichier de retour.