Объединение маршрутов в NodeJ со значениями после отправки ответа API - PullRequest
0 голосов
/ 28 мая 2018

Я хочу связать маршруты в NodeJ со значениями после отправки ответа API в end-ser,

ПОЧЕМУ:> Загруженные файлы будут несколько большими (5-50 МБ каждый) и требуют некоторой обработки, не могутзаставить моего пользователя API ждать / тайм-аут, пока мой код NodeJS работает .. так что нужно, 1: выгрузить файлы и немедленно отправить их пользователю, обработать файлы (несколько обещаний) и вернуть / зарегистрировать успех / неудачу для системы уведомлений.

Мои отдельные блоки кода выполнены и работают нормально (т. Е. Служба загрузки и служба обработки файлов хорошо работают при тестировании и работают хорошо при индивидуальном тестировании.)

теперь с API для загрузки на месте, я имеюдобавлен следующий код:

router.post('/upload', upload.array('upload_data', multerMaxFiles), (req, res, next) => {
 ////some uploading and processing stuff - works nicely
 res.json({ 'message': 'File uploaded successfully.' });// shown to API client nicely
 console.log("what next? " + utilz.inspect(uploaded_file_paths)) //prints file names on console
 next();
});

ПРОБЛЕМА:

app.use('/api', uploadRoute); //The above code route

//want some processing to be done

app.use(function(req, res, next) {

**want those uploaded file names here**
tried with few response object options but stabs with error
});

ИЛИ использовать что-то вроде ....

app.use(someFunction(uploaded_file_names)); **want those uploaded file names as params**

PS: Любое обещание после успешной загрузки файла приведет к «Ошибка: невозможно установить заголовки после их отправки.», Поэтому бесполезно писать что-либо там.

Любые люди с предложениями.

- N Baua

Ответы [ 3 ]

0 голосов
/ 28 мая 2018
  //STEP (1)
  //Example simulate upload multiple files with chained api calls. In this example the parameters "idFile" and "arrayidFileExample" are helpful.
  //You should create and send this data from view.
  {
    "idFile": "04fe640f6e4w",                                                                        //id first file                          
    "arrayidFileExample": ["04fe640f6e4w","03g5er4g65erg","g0er1g654er65g4er","0g4er4g654reg654re"]  //simulate idFiles array from view
  }


//STEP (2)
//your upload files api
app.post('/upload', function(req, res) {

    //Express headers, no important in this code
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");


    let arrayIdFiles = req.body.arrayidFileExample;       //create arrayIdFiles

    let isBlock = false;                                  //flag to block call loop to api
    let countIndex = 0;
    let currentIndex = 0;

    //STEP (3)
    //If "arrayIdFiles" index is not exist, set isBlock to true. Remeber flag to block call loop to api
    for(let count in arrayIdFiles) {
        if(req.body.idFile == arrayIdFiles[count]) {
            console.log("current index --> ", countIndex)
            countIndex++;
            console.log("next index --> ", countIndex)
            if(arrayIdFiles[countIndex] == undefined) {
                isBlock = true;
            }
            break;
        }
        countIndex++;
        currentIndex++;
    }

    //STEP (4)
    //If isBlock is equal false, call get upload api with next idFile. this is simulate "recursive api loop"
    if(isBlock == false) {
        postUploadFile(
          'http://localhost:3500/upload',
          {
            "idFile":arrayIdFiles[currentIndex + 1], //send next idFile from arrayIdFiles
            "arrayidFileExample": arrayIdFiles       //initial arrayIdFiles
          });
    }

    //STEP (6)
    //response json example
    const json = JSON.stringify({
    error:false,
    statusCode: 200,
    body:{
        message:'current id file '+req.body.idFile,
    }
    });

    res.write(json);
    return res.end();
});

    //STEP (5)
    //call "/upload" api post
const postUploadFile = (url = '', body = {}) => {
    return new Promise((resolve, reject)=>{
      axios.post(url, body).then(response => {
          return resolve(response.data);
      }).catch(error => {});
    });
};


//server listen instance
server.listen(3500,() => {
});
0 голосов
/ 28 мая 2018

Как только вы отправили ответ обратно в браузер (чтобы избежать его истечения во время длительного времени обработки), этот http-запрос будет выполнен.Вы не можете отправить на него больше данных, и попытка сделать это вызовет ошибку на стороне сервера.Вы не можете «соединять маршруты» так, как просили, как вы, кажется, хотите, потому что вы просто не можете отправить больше данных по этому HTTP-запросу после отправки первого ответа.

Существует два общихспособы решения этой проблемы.

  1. В качестве части вашего первоначального ответа отправьте обратно идентификатор транзакции, а затем каждые несколько секунд отправляйте опрос клиентов с помощью вызова Ajax, спрашивающего, каков окончательный статус.из этой транзакции.Сервер может возвращать «в процессе» до тех пор, пока он не будет окончательно выполнен, а затем он может вернуть окончательный статус.

  2. Вы можете подключить соединение webSocket или socket.io от клиента к серверу.Как часть вашего первоначального ответа на загрузку, отправьте обратно идентификатор транзакции.Затем, когда транзакция выполняется на стороне сервера, он отправляет уведомление о соединении webSocket или socket.io для этого конкретного клиента с ID транзакции с окончательным статусом.Затем клиент может ответить соответственно этому окончательному статусу.Вы можете оставить соединение webSocket / socket.io открытым для использования с другими запросами или затем закрыть это соединение.

Используя любой из этих методов, вы также можете вернуть / отправить значение прогресса(например, процент выполнения), который клиент может использовать для отображения прогресса выполнения.Как правило, это очень полезно на стороне клиента, чтобы не дать нетерпеливому пользователю отказаться от обновления страницы.Если они увидят, что обработка продолжается, они не перестанут думать, что, возможно, она перестала работать.

0 голосов
/ 28 мая 2018

Это должно работать с res.write().Но это зависит от кеша ваших клиентов, я думаю.

Я пытался это , но он не работает в моем firefox.

app.get('/test', function(req, res) {
  var count     = 0;
  var interval  = setInterval(function() {
    if (count++ === 100) {
      clearInterval(interval);
      res.end();
    }
    res.write('This is line #' + count + '\n');
  }, 100);
});

После того, как я увеличил частоту иколичество операций записи, похоже, работает.

Так что попробуйте:

router.post('/upload', upload.array('upload_data', multerMaxFiles), (req, res, next) => {
 ////some uploading and processing stuff - works nicely
 res.write(JSON.stringify({ 'message': 'File uploaded successfully.' }));// shown to API client nicely
 console.log("what next? " + utilz.inspect(uploaded_file_paths)) //prints file names on console
 next();
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...