Ndoe js SSE res.write () не отправляет данные в потоках - PullRequest
0 голосов
/ 24 апреля 2020

Я пытаюсь добавить SSE (события, отправленные сервером) в NodeJs, но когда я отправляю ответ, используя res.write(), данные не отправляются, а только после записи res.end() все данные отправляются на в то же время.

Я уже нашел много сообщений на Github, StackOverflow, касающихся этой проблемы и везде, где упоминается использование res.flush() после каждого res.write(), но это тоже не работает для меня, также я не использую любой модуль сжатия явно.

Код на стороне сервера

Может кто-нибудь, пожалуйста, скажите мне, есть ли способ, которым я могу сделать эту работу.

const express = require('express')

const app = express()
app.use(express.static('public'))

app.get('/countdown', function(req, res) {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  })
  countdown(res, 10)
})

function countdown(res, count) {
  res.write("data: " + count + "\n\n")
  if (count)
    setTimeout(() => countdown(res, count-1), 1000)
  else
    res.end()
}

app.listen(3000, () => console.log('SSE app listening on port 3000!'))

Код на стороне клиента

<html>
<head>
<script>
  if (!!window.EventSource) {
    var source = new EventSource('/countdown')

    source.addEventListener('message', function(e) {
      document.getElementById('data').innerHTML = e.data
    }, false)

    source.addEventListener('open', function(e) {
      document.getElementById('state').innerHTML = "Connected"
    }, false)

    source.addEventListener('error', function(e) {
      const id_state = document.getElementById('state')
      if (e.eventPhase == EventSource.CLOSED)
        source.close()
      if (e.target.readyState == EventSource.CLOSED) {
        id_state.innerHTML = "Disconnected"
      }
      else if (e.target.readyState == EventSource.CONNECTING) {
        id_state.innerHTML = "Connecting..."
      }
    }, false)
  } else {
    console.log("Your browser doesn't support SSE")
  }
</script>
</head>
<body>
  <h1>SSE: <span id="state"></span></h1>
  <h3>Data: <span id="data"></span></h3>
</body>
</html>

Решение - я использовал nginx для обратного прокси-сервера, поэтому это происходило, поэтому я попробовал это решение, и оно работало :)

EventSource / Отправленные сервером события через Nginx

1 Ответ

1 голос
/ 25 апреля 2020

Если ваш Express сервер находится за брандмауэром или прокси-сервером, они часто будут ждать, пока сервер не закроет соединение, прежде чем отправлять весь ответ. Вместо этого вам нужно иметь соединение между браузером и сервером, которое позволяет 'Connection': 'keep-alive'.

...