Как сбросить данные клиенту сразу после записи res.write() перед res.end() в Express.js?

Я создал клиент Apache Kafka с использованием Kafkajs, и я пытаюсь прочитать сообщения из темы в Kafka. Он работает нормально, если я console.log(сообщение). Но я хочу отправлять сообщение клиенту каждый раз, когда создается / записывается новое сообщение в теме, которую потребитель слушает от производителей, сохраняя при этом соединение.

 // function, which is being called whenever it's specified route is being requested
 async readMessage(req, res, next, consumer) {
    const resMessage = {};

    res.writeHead(200, {'Content-Type': 'text/plain'});

    await consumer.run({
        eachMessage: async ({ topic, partition, message }) => {  
            res.write(message.value.toString());
        },
    });

    // res.send(resMessage);
}

Но после того, как я отправлю данные на сервер express.js, res.write() не отправляет данные клиенту (я использую Postman в качестве своего клиента Node.js). Как мне очистить данные, записанные в res.write(), до вызова res.end()?

1 ответ

Решение

res.write()отправляет данные (без буферизации Express или nodejs), как только вы его вызываете. Я проследил это в отладчике и увидел, как он отправляет данные без задержки. Операционная система, обслуживающая алгоритм Нэгла, может кратковременно буферизовать его, но это будет только очень короткая задержка (миллисекунды). Итак, данные отправляются клиенту. Гораздо более вероятно, что ваша проблема связана с http-клиентом, который получает данные.

Большинство http-клиентов рассчитаны на запрос / ответ. Отправьте запрос, дождитесь полного ответа, а затем уведомите вызывающего абонента. Итак, если вы хотите получать регулярные данные из потока http по мере его поступления, вам понадобится нетрадиционный клиент http, который будет уведомлять вас, когда данные поступают таким образом. Вероятно, вам также потребуется изобрести какой-то протокол, который позволит клиенту узнать, когда прибыл полный фрагмент, поскольку пакеты можно разбивать или группировать случайным образом.

Что может быть проще, чем использовать для этого http, - это использовать реальный протокол на основе сообщений, такой как webSockets или socket.io, который явно разработан для того, что вы пытаетесь делать. Клиент установит соединение с сервером, и тогда сервер сможет отправлять сообщения клиенту в любое время. webSocket или socket.io основаны на сообщениях, поэтому они уже делают за вас всю работу по разграничению сообщения, его упаковке, доставке, распаковке и уведомлению получателя о прибытии сообщения. Это именно то, для чего были разработаны webSocket / socket.io.

Для односторонней отправки сообщений (от сервера к клиенту) вы также можете использовать Server Sent Events, который является расширением http.

Другие вопросы по тегам