首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何关闭服务器上的“服务器发送的事件”-connection?

如何关闭服务器上的“服务器发送的事件”-connection?
EN

Stack Overflow用户
提问于 2011-06-30 20:17:16
回答 6查看 8.8K关注 0票数 6

关于此规范:http://www.w3.org/TR/eventsource/

如何关闭服务器上打开的连接?在客户端,这很简单,只需调用close(),但是我应该在服务器端做什么呢?杀了就好?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-10-07 18:02:33

node.js:

代码语言:javascript
运行
复制
http.createServer(function (req, res) {

    //...

    // client closes connection
    res.socket.on('close', function () {
      res.end();
      //...
    });

});

单点登录服务器在node.js中的实现参见示例:

https://github.com/Yaffle/EventSource/blob/master/nodechat/server.js

票数 3
EN

Stack Overflow用户

发布于 2020-07-12 04:33:34

因此,我到处寻找内置到协议中的解决方案,但似乎没有。如果您的服务器调用response.emit('close')response.end(),客户端将把它当作错误处理,并尝试重新连接到服务器。(至少在Chrome的情况下,它将尝试无限期地重新连接,除非它认为网络错误是致命的)。

因此,无论以何种方式,您的客户端都必须关闭连接。这就只剩下两个选择了。第一,简单地假设来自服务器的任何错误都应该关闭EventSource。

代码语言:javascript
运行
复制
const sse = new EventSource('/events')
sse.onmessage = m => console.log(m.data)
sse.onerror = () => sse.close()

不过,上面的内容还有一些需要改进的地方。我们假设网络错误是正常关机,但事实可能并非如此。也可能在某些情况下,我们确实需要重新连接行为。

所以,为什么我们不直接要求客户端优雅地关闭自己呢!我们有一种从服务器向客户端发送消息的方法,所以我们需要做的就是从服务器发送一条消息,上面写着“关闭我”。

代码语言:javascript
运行
复制
// client.js
const maxReconnectTries = 3

let reconnectAttempts = 0
const sse = new EventSource('/events')
sse.onmessage = m => {
  const { type, data } = JSON.parse(m.data)
  if (type === 'close') sse.close()
  else console.log(data)
}
sse.onerror = () => {
  if (reconnectAttempts > maxReconnectTries) {
    sse.close()
    alert("We have a baaad network error!")
  } else {
    reconnectAttempts++
  }
}
代码语言:javascript
运行
复制
// server.js
const express = require('express')


function sendEvent(res, type, data) {
  res.write(`data: ${JSON.stringify({ type, data })}\n\n`)
}

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

  let manualShutdown
  request.on('close', () => {
    console.log('disconnected.')
    clearTimeout(manualShutdown)  // prevent shutting down the connection twice
  })
  
  sendEvent(res, 'message', `Ping sent at ${new Date()}`)

  // when it comes time to shutdown the event stream (for one reason or another)
  setTimeout(() => {
    sendEvent(res, 'close', null)
    // give it a safe buffer of time before we shut it down manually
    manualShutdown = setTimeout(() => res.end(), clientShutdownTimeout)
  }, 10000)
}

const clientShutdownTimeout = 2000
const app = express()
app.get('/events', sseHandler)
app.listen(4000, () => console.log('server started on 4000'))

这涵盖了安全的客户端/服务器实现所需的所有领域。如果服务器出现问题,我们会尝试重新连接,但仍然可以在出现故障时通知客户端。当服务器想要关闭连接时,它会要求客户端关闭连接。两秒钟后,如果客户端没有关闭连接,我们可以假定出现了错误,并关闭连接服务器端。

我们在这里做的是在服务器发送事件的基础上构建一个协议。它有一个非常简单的接口:{ "type": "close" }告诉客户端关闭服务器,{ "type": "message", "data": {"some": "data" }告诉客户端这是一条常规消息。

票数 6
EN

Stack Overflow用户

发布于 2011-07-16 17:58:25

我猜你只是关闭了连接(杀死它)。我还没有看到任何关于优雅断开的讨论。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6534572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档