Подпишитесь на отзывы о долго обрабатываемых запросах на сервере NodeJS от клиента

Я создал сервер Node JS, который выполняет следующие действия:

  1. Загружает медиафайлы (видео и изображения) на сервер с помощью multer
  2. Если медиафайлом является изображение, измените его размер, используя резкое изображение.
  3. Если медиа - это видео, измените его размер и сожмите с помощью fluent-ffmpeg.
  4. Загрузить файлы в хранилище Firebase для резервного копирования

Все это рабочее знаю бегло. Проблема в том, что при большом размере загружаемого файла обработка запроса занимает много времени. Итак, я хочу показать некоторый прогресс на стороне клиента, как показано ниже:

  • Состояние 1. Медиа загружается -> n%
  • Состояние 2. СМИ соглашаются
  • Состояние 3. Медиа загружается в облако -> n%
  • Состояние 4. Результат -> JSON = {status: "ok", uri: .., cloudURI: .., ..}

API хранилища Firebase имеет такую ​​функциональность, когда мы создаем задачу загрузки, как показано ниже:

let uploadTask = imageRef.put(blob, { contentType: mime });
uploadTask.on('state_changed', (snapshot) => {
  if (typeof snapshot.bytesTransferred == "number") {
    let progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
    console.log('Upload is ' + progress + '% done');
  }
});

Я обнаружил, что это можно реализовать с помощью веб-сокетов, мне интересно, есть ли другие методы для этого.

Проблема также описана здесь: http://www.tugberkugurlu.com/archive/long-running-asynchronous-operations-displaying-their-events-and-progress-on-clients

И есть один из методов доступа к частичному ответу с помощью AJAX или WebSockets? Но ищу более гибкое и профессиональное решение.


person M.Aliyev    schedule 31.10.2019    source источник


Ответы (1)


Я решил эту проблему с помощью подписок GraphQL. Тот же подход можно реализовать с помощью WebSockets. Ниже приведены шаги для решения этой проблемы:

  1. Размещать файлы на сервер загрузки

  2. Сгенерировать уникальный идентификатор операции и отправить его в качестве ответа клиенту.

Ex: response = {op: "A78HNDGS89NSNBDV7826HDJ"}

  1. Создать подписку по opID

Ex: subscription { uploadStatus(op: "A78HNDGS89NSNBDV7826HDJ") { status }}

  1. Каждый раз при изменении статуса отправляйте запрос в конечную точку GraphQL, которая публикует данные в pubsub. Чтобы отправить запрос GraphQL с сервера nodejs, вы можете использовать https://github.com/prisma-labs/graphql-request

Ex:

const { request } = require('graphql-request');
const GQL_URL = "YOUR_GQL_ENDPOINT";
const query = `query {
    notify ("Status text goes here")
}`

request(GQL_URL, query).then(data =>
  console.log(data)
)

функция распознавания уведомлений публикует данные в pubsub

 context.pubsub.publish('uploadStatus', {
     status: "Status text"
 });

Если у вас более сложная архитектура, вы можете использовать брокеры сообщений, такие как RabbitMQ, Kafka и т. Д.

Если кто-то знает другие решения, дайте нам знать)

person M.Aliyev    schedule 05.11.2019