在长时间处理帖子请求期间发送websocket消息

我有一个nodejs / express / socket.io应用程序,它处理客户端发送的文件(表达发布请求),因为该过程可能很长(超过10分钟),所以我想使用websocket更新客户端关于处理。

问题是服务器只能在post request函数中执行一次socket.emit。服务器未发送任何消息并且websocket似乎仍处于连接状态。

==>服务器端

// 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,tmp_upload_folder));
    },filename: function (req,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,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

即使处理继续进行,服务器也只会在app.post函数中发送第一个socket.emit,而不会发送所有其他socket.emit。

siqi111 回答:在长时间处理帖子请求期间发送websocket消息

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3165537.html

大家都在问