1

我尝试使用Deno ws重新加载文档,但是第二次重新加载后会抛出错误
Uncaught ConnectionReset: Socket has already been closed throw new Deno.errors.ConnectionReset("Socket has already been closed");

var ws = new WebSocket("ws://127.0.0.1:8080/ws")
    ws.onopen = function () {
      ws.send('ws open')
      console.log('ws open');
    }
    ws.addEventListener("message", (e) => {
      if (e.data === 'fileUpdate') {
        // ws.send('close')
        location.replace(location.href);
      }
    })

似乎location.replace(location.href)引发错误任何解决方案?

4

2 回答 2

2

发生错误是因为您在套接字关闭后发送消息。

当您这样做时:location.replace(location.href);刷新页面并关闭当前套接字。

您可以捕获错误,也可以ws.isClosed在发送消息之前进行检查。

for await (const e of ws) {
  if (e === 'close') {
    ob.remove("fileUpdate")
    continue
  }
  ob.on("fileUpdate", () => {
    console.log('sending')
    if(!ws.isClosed)
       ws.send("fileUpdate")
  })
}

虽然这将解决错误,但它不会解决原因。您的事件在套接字关闭ob.on('fileUpdate')触发。您应该清除 WebSocket 关闭事件上的侦听器,您可以使用ws.isWebSocketCloseEvent

import { acceptWebSocket, isWebSocketCloseEvent } from "https://deno.land/std@0.51.0/ws/mod.ts";
/* ... */
for await (const e of ws) {
  if(isWebSocketCloseEvent(e) || e === 'close') {
    // clear listeners here
    ob.remove("fileUpdate")
    // if e === 'close' you may want to close the socket
  }
}

于 2020-05-16T09:22:58.647 回答
0

这是 Deno 代码:

import { Application } from "https://deno.land/x/abc/mod.ts"; 
import { acceptWebSocket } from "https://deno.land/std@0.51.0/ws/mod.ts";
new Application()
  .file("/", "./index.html")
  .file("/module.js", "./module.js")
  // .file("sw.js", "ServiceWorker.js")

  .get('/ws', async (c: any) => {
    const { conn, headers, r: bufReader, w: bufWriter } = c.request;
    const ws = await acceptWebSocket({
      conn,
      headers,
      bufReader,
      bufWriter,
    });
    for await (const e of ws) {
      if (e === 'close') {
        ob.remove("fileUpdate")
        continue
      }
      ob.on("fileUpdate", () => {
        ws.send("fileUpdate")
      })
    }
  })
  .start({ port: 8080 })

ob像这样 :

class Ob {
  private list: ObList[] = []
  send(event: string) {
    this.list.forEach((e: ObList) => {
      if (e.event === event) {
        e.cb && e.cb()
      }
    })
  }
  on(event: string, cb: Function) {
    this.list.push({ event, cb })
  }
  remove(event:string){
    this.list=this.list.filter((e:ObList)=>{
      return e.event!==event
    })
  }
}

框架是abc

于 2020-05-16T08:41:23.720 回答