У меня есть приложение 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 не отправляются.