Node.js SSE res.write() 不在流中发送数据 [英] Node.js SSE res.write() not sending data in streams

查看:61
本文介绍了Node.js SSE res.write() 不在流中发送数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 NodeJs 中添加 SSE(服务器发送事件),但是当我使用 res.write() 发送响应时,数据没有被发送,但只有在写入 之后res.end() 所有数据同时发送.

I am trying to add SSE(Server sent events) in NodeJs, But when I am sending response using res.write() the data is not getting sent, but only after writing res.end() all data is being sent at the same time.

我已经在 Github、StackOverflow 上找到了很多关于这个问题的帖子,并且到处都提到在每个 res.write() 之后使用 res.flush()但这对我也不起作用,我也没有明确使用任何压缩模块.

I have already found many posts on Github, StackOverflow, regarding this issue and everywhere it is mentioned to use res.flush() after every res.write() but that too isn't working for me, also I am not using any compression module explicitly.

服务器端代码

谁能告诉我有什么方法可以让我完成这项工作.

Can anyone please tell me is there any way I can make this work.

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 用于反向代理,这就是它发生的原因,所以我尝试了这个解决方案并且它奏效了 :)

Solution - I was using nginx for reverse proxy that's why it was happening so I tried this solution and it worked :)

事件源/服务器通过 Nginx 发送事件

推荐答案

如果您的 Express 服务器位于防火墙或代理服务器之后,它们通常会等到服务器关闭连接后再发送整个响应.相反,您需要在浏览器和服务器之间建立一个允许 'Connection': 'keep-alive' 的连接.

If your Express server is behind a firewall or proxy server, they will often wait until the server closes the connection before sending the entire response. Instead, you need to have a connection between the browser and the server that allows the 'Connection': 'keep-alive'.

这篇关于Node.js SSE res.write() 不在流中发送数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆