页面关闭后无法在服务人员中维护 websocket

Posted

技术标签:

【中文标题】页面关闭后无法在服务人员中维护 websocket【英文标题】:unable to maintain websocket in service worker after page closed 【发布时间】:2019-11-25 01:09:18 【问题描述】:

我在 service-worker 中使用 websocket。它在网页打开时运行良好,但如果网页关闭,websocket 会断开连接并停止工作,这让我很困惑。

其实因为在中国,我无法使用google FCM和PUSH api,所以我想使用websocket来推送消息。

我的程序是在 Create-react-app 下构建的

//serviceWorker.js
const WebSocketConnect = () => 
  let ws = new WebSocket("ws://127.0.0.1:8000/ws/news/")
  ws.onopen = function() 
      setInterval(() => 
          if ( 'readyState' in ws && ws.readyState === 1 ) 
              ws.send('Hay')
          
      , 5000)
  

  ws.onmessage = function(e) 
      console.log('Message:', e.data)
  

  ws.onclose = function(CloseEvent) 
      ws.close()
      console.log(`Socket is clossed, code: $CloseEvent.code - reason: $CloseEvent.reason`)
      setTimeout(() => 
          WebSocketConnect()
      , 3000)
  

  ws.onerror = function(err) 
      console.log(err)
      //console.error('Socket encountered error: ', err.message, 'Closing socket')
      ws.close()
  


WebSocketConnect()

【问题讨论】:

【参考方案1】:

您的服务工作者很可能正在停止并且正在关闭 WebSocket。

浏览器限制服务工作者脚本在关闭之前可以运行多长时间。处理 FetchEvent、MessageEvent、PushEvent 等事件将唤醒 worker 并允许其运行,直到事件被处理。大多数浏览器会在服务工作线程空闲大约 30 秒后停止。

浏览器也会在一段时间后超时通过 waitUntil() 保持打开的事件以停止工作程序。在大多数浏览器中,这些超时通常会在大约 5 分钟后发生。

当网站没有打开的窗口时,浏览器通常会更努力地停止服务工作线程,因为在后台运行可能会被滥用。

我不相信 Web 平台目前有能力在不打开站点窗口的情况下在后台连续运行 WebSocket 之类的东西。

【讨论】:

感谢您的回答!如果用户无法使用 FCM 和任何其他谷歌服务,即使没有打开站点窗口,你还有其他想法向用户发送消息吗? 我相信推送通知是为该用例设计的 API。不过,我不确定这是否满足您不依赖谷歌服务的需求。 这同样适用于不能使用外部推送服务的气隙环境。对此的任何解决方案都将受到欢迎!

以上是关于页面关闭后无法在服务人员中维护 websocket的主要内容,如果未能解决你的问题,请参考以下文章

jetty 9,websockets 和关闭服务器端的 websocket 连接

连接webSocket客户端时节点httpServer无法关闭

如何在WebSocket的服务器侧检测客户端的断开连接

无法连接到 symfony 中的 websocket 服务器

为啥 MongooseIM 会在 60 秒后关闭 websocket 连接?

WebSocket 在 1000 条消息后关闭