为了账号安全,请及时绑定邮箱和手机立即绑定

获取 WebSocket 错误关闭发送当我导航到其他页面

获取 WebSocket 错误关闭发送当我导航到其他页面

Go
MYYA 2022-08-24 16:12:51
我收到错误websocket:当我尝试将数据从服务器端发送到客户端(仪表板页面)时,关闭发送。当我导航到主页并返回到仪表板页面时发生错误。最初使用仪表板页面时一切正常 我的仪表板页面代码  let socket = new ReconnectingWebSocket("ws://127.0.0.1:8004/wsendpoint");        console.log("Attempting Connection...");        socket.onopen = () => {            console.log("Successfully Connected");                  };        socket.onclose = event => {            console.log("Socket Closed Connection: ", event);                 };        socket.onerror = error => {            console.log("Socket Error: ", error);                 };        socket.onmessage = function (event) {            console.log("message received: " + event.data);        }我的服务器端代码(编写器和读取器)func wsEndpoint(w http.ResponseWriter, r *http.Request) {    upgrader.CheckOrigin = func(r *http.Request) bool { return true }    // upgrade this connection to a WebSocket connection    ws, err := upgrader.Upgrade(w, r, nil)    if err != nil {        log.Println("upgrade error %s", err)    }    defer ws.Close()    go writer(ws)     go reader(ws)}写入器,当新数据从数据库传入时从通道获取数据func writer(conn *websocket.Conn) {    for {        singleset := <-singleorder // get data from channel        jsonString, err := json.Marshal(singleset )         err = conn.WriteMessage(1, []byte(jsonString))        if err != nil {            log.Println(err)        }    }读取器,从客户端读取数据func reader(conn *websocket.Conn) {    for {        _, p, err := conn.ReadMessage() //what is message type?        if err != nil {            log.Println("there is errors%s", err)            return        }    }}我还收到错误 WebSocket 在建立连接之前被关闭,而重新连接-websocket.min.js:1 WebSocket 连接到“ws://127.0.0.1:8004/wsendpoint”失败:WebSocket 在建立连接之前被关闭。正如你所看到的,所有的代码都非常简单,因为我刚刚开始学习websocket并遵循简单的教程。我试图在网上搜索,但网络工作者对我来说似乎有点复杂,并看到了乒乓球方法,但我不确定如果我导航它是否仍然有效。我可以在主页上建立websocket,以便连接不会关闭吗?因为我在客户端只有两个页面。提前感谢您有关如何处理这些情况的任何指导!
查看完整描述

1 回答

?
潇湘沐

TA贡献1816条经验 获得超6个赞

处理离开页面、页面关闭或错误的导航的基本策略是:客户端在页面加载时创建 websocket 连接。服务器期望客户端连接来来去去,并在客户端连接错误时清理资源。

这就是为什么您收到错误“websocket:关闭发送”的原因:当用户离开页面时,浏览器会向服务器发送一条关闭消息,作为websocket关闭握手的一部分。Gorilla 包通过向客户端发送另一条关闭消息来响应关闭消息。从那时起,服务器无法在连接上发送消息。发送关闭消息后,连接从写入方法返回错误。

关闭消息作为 websocket 读取方法中的错误返回。若要解决此问题,请修改代码以处理常规错误。无需专门处理闭合握手。

下面是更新的代码。该函数为读取器创建一个通道,以向编写器发出读取器已完成的信号。该语句被删除,因为读取者和写入者将负责关闭连接。wsEndpointdefer ws.Close()

func wsEndpoint(w http.ResponseWriter, r *http.Request) {


    upgrader.CheckOrigin = func(r *http.Request) bool { return true }

    // upgrade this connection to a WebSocket connection

    ws, err := upgrader.Upgrade(w, r, nil)

    if err != nil {

        log.Println("upgrade error %s", err)

    }


    done := make(chan struct{})     

    go writer(ws, done) 

    go reader(ws, done)

}

读取器在返回时关闭连接。它还关闭通道以向写入器发出读取器已完成的信号。done


func reader(conn *websocket.Conn, done chan struct{}) {

    defer conn.Close()

    defer close(done)

    for {

        _, p, err := conn.ReadMessage() //what is message type?

        if err != nil {

            log.Println("there is errors%s", err)

            return

        }

    }

}

编写器还会在返回时关闭连接。当连接关闭时,对连接的读取会立即返回一个错误,导致读取 goroutine 完成。编写器在频道上等待。当通道被读取器关闭时,通道上的接收将产生零值。编写器在写入错误时返回,而不是像问题中那样永远循环。done


func writer(conn *websocket.Conn, done chan struct{}) {

    defer conn.Close()

    for {

        select {

        case <-done:

            // the reader is done, so return

            return

        case singleset := <-singleorder: // get data from channel

            jsonString, err := json.Marshal(singleset ) 

            err = conn.WriteMessage(1, []byte(jsonString))

            if err != nil {

                log.Println(err)

                return

            }

        }

    }

}

应用程序应期望由于多种原因(包括用户离开页面)而关闭连接。


发送到通道的代码可能需要知道连接已关闭,但我们在这里看不到该代码。我会留给你来弄清楚如何处理这个问题。singleorder


查看完整回答
反对 回复 2022-08-24
  • 1 回答
  • 0 关注
  • 128 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信