Отправка сообщения веб-сокета во время длительной обработки почтового запроса - PullRequest
0 голосов
/ 04 ноября 2019

У меня есть приложение nodejs / express / socket.io, которое обрабатывает файл, отправленный клиентом (экспресс-запрос по почте), так как этот процесс может быть очень длинным (более 10 минут). Я хочу использовать websocket для обновления клиентаоб обработке.

проблема в том, что сервер может сделать socket.emit только один раз в функции post post. после того, как ничего не отправлено с сервера и кажется, что веб-сокет все еще подключен.

==> сторона сервера

// Déclaration des modules necessaires
// =======================
var express = require("express"); // middleware pour la gestion des requetes http
var app = express(); // déclaration du middleware express
var http = require("http"); // module pour l'utilisation de http
var httpserver = http.createServer(app);
var io = require("socket.io")(httpserver);
var ejs = require("ejs"); // moteur de rendu pour les pages web
var bodyParser = require("body-parser"); // parser des options et données envoyées dans les URL ou via les requetes POST
var path = require("path"); // module pour la gestion des noms de fichiers
var multer = require("multer"); // envoi de fichier
var fs = require("fs-extra");
var fsbasic = require("fs");
var AdmZip = require("adm-zip"); // gestion de la décompression ZIP
var parser = require('fast-xml-parser');

var public_folder = "public"; // Répertoires contenant les fichiers statiques servis aux pages web (js/css/images)
var views_folder = "views"; // Répertoires contenant les fichiers statiques html
var tmp_upload_folder = "tmp"; //repertoire temporaire d'extraction'
var appname = "Kapigraph";

var xmlparseroptions = {
    attributeNamePrefix: "",
    attrNodeName: false,
    ignoreAttributes: false,
    ignoreNameSpace: true,
    allowBooleanAttributes: false,
    parseNodeValue: false,
    parseAttributeValue: false,
    trimValues: true,
    cdataTagName: "false" //default is 'false'
}

// Utilisation de "body parser" pour récupérer les informations fournies dans les requetes POST et les URL
app.use(bodyParser.urlencoded({
    extended: false
}));
app.use(bodyParser.json());
app.use(compression());

// Configuration du framework Express
app.use(express.static(path.join(__dirname, public_folder)));
app.engine("html", ejs.renderFile); // configuration du moteur de rendu des pages web
app.set("view engine", "html");
app.set("views", path.join(__dirname, views_folder)); // Répertoire du template html
//app.use(express.limit('15mb'));
httpserver.timeout = 240000;


function makeid(len) {
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    for (var i = 0; i < len; i++) {
        text += possible.charAt(Math.floor(Math.random() * possible.length));
    }
    return text;
}

var storage = multer.diskStorage({
    destination: function (req, file, callback) {
        "use strict";
        req.sessionID = makeid(15);
        callback(null, path.join(__dirname, tmp_upload_folder));
    },
    filename: function (req, file, cb) {
        "use strict";
        var original_name = file.originalname.replace(/\s/g, "_");
        cb(null, original_name);
    }
});

var upload = multer({
    storage: storage
}).fields([{
    name: "pm",
    maxCount: 1
}]);

app.get("/", function (req, res) {
    "use strict";
    res.render("index", {
        title: appname,
        message: "Bienvenue sur " + appname
    });
});

io.on('connection', function (clientsocket) {
    console.log("client connected");
    //console.log(socket);
    clientsocket.emit("data", "connecté");

    clientsocket.on('disconnect', function () {
        console.log('user disconnected')
    });

    clientsocket.on("ack", function(data) {
        console.log("message received: " + data);
    })

    app.post("/sendkpiarchive", upload, function (req, res) {
        "use strict";
        var remote_ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
        var fullUrl = req.protocol + "://" + req.get("host") + req.originalUrl;
        var result = {
            status: "OK",
            data: [],
            message: "Traitement en cours",
        };

        console.log("connexion depuis " + remote_ip + " | url: " + fullUrl);
        var destdir = path.join(__dirname, tmp_upload_folder, req.sessionID);
        clientsocket.emit("data", "traitement du fichier en cours");

        ...
        => data processing
        ...

        clientsocket.emit("data", "uncompressing file");
        ...
        clientsocket.emit("data", "reading file");
        ...
        clientsocket.emit("data", "parsing file");
        ...


        console.log("Done!");
        result.status = "success";
        result.message = "Archive traitée";
        console.log(result.data.length);
        fs.remove(destdir, function (err) {
            if (err) {
                console.log(err);
            }
        });
        clientsocket.emit("data", result);
        return res.status(200).send(result);
    });
});

==> сторона клиента

var socket = io.connect($(location).attr("href"), {
    transports: ["websocket"],
    forceNew: true,
    timeout: 2000000
});

socket.on("data", function(message) {
     console.log("data: ", message);
     socket.emit("ack", "ok");
});

на стороне сервера я получил:

client connected
message received: ok
connexion depuis ::ffff:127.0.0.1 | url: http://127.0.0.1:5004/sendkpiarchive

на стороне клиента я только что получил:

data:  connecté
data:  traitement du fichier en cours

, даже если обработка продолжается, сервер отправил только первый socket.emit в приложении. Функция post все остальные socket.emit не отправляются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...