javascript - 刷新浏览器后 websocket 客户端 onmessage 中断

标签 javascript go websocket

我有一个用 go 编写的 Websocket 服务器,包 github.com/gorilla/websocket

服务器有 2 个循环用于接收和发送消息。 http 处理程序的实现如下所示:

upgrader, errChan := websocket.Upgrader{}, make(chan error)

ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
}

// incoming messages

go func() { 
    for {
        message := Message{}
        if err := ws.ReadJSON(&message); err != nil {
            errChan <- err
        }
        handleMessage(message)
    }
}()

// outgoing messages 

go func() { 
    for {
        message := <-global.outgoingMessage
        if err = ws.WriteMessage(websocket.TextMessage, message); err != nil {
            errChan <- err
        }
    }
}()

err = <- errChan
ws.Close()

客户端应用程序使用 React,应用程序使用消息作为状态。启动应用程序时,会建立 websocket 连接,并且 onopen 回调会触发对初始数据的请求。响应由用于应用程序状态的 onmessage 捕获。实现如下所示:

var ws = new WebSocket("ws://localhost:8080/app")

ws.onerror = function(err) {
    alert(err)
}
ws.onmessage = function(m) {
    var state = JSON.parse(m.data)
    global.app.setState(state) 
}
ws.onopen = function() { 
    ws.send('{"type":"init"}')
}

通过此设置,我注意到的是我第一次启动应用程序并浏览到页面时一切正常。刷新浏览器后,它不再有效。我可以调用 ws.send('{"type":"init"}') 并查看服务器发送的响应,但不会触发 onmessage 回调.在多次尝试调用 ws.send('{"type":"init"}') 之后,onmessage 最终被调用一次并加载应用程序状态。如果我终止并重新启动该应用程序,则会发生相同的行为。

想法?

最佳答案

看起来所有输出 goroutines 都从单个 channel global.outgoingMessage 接收,并且发送到该 channel 的消息不足以满足所有正在运行的输出 goroutines。

如果应用程序的目的是向所有连接的客户端广播,那么我建议遵循 Gorilla chat example 中的集线器模式。 .

旁白:应用程序泄漏了 goroutines。参见 this question寻求解释。

关于javascript - 刷新浏览器后 websocket 客户端 onmessage 中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40902841/

相关文章:

c# - Jquery AJAX 与 ASP.NET WebMethod 刷新整个页面

amazon-web-services - AWS Firehose 和 Go 问题

go - 如何让颜色与 golang tabwriter 一起使用?

python - 将套接字从 python 发送到 Meteor (node.js)

ssl - 在 Nest.js 中的 3 个不同端口上使用安全 Websocket

javascript - 在 React Hook 中设置一个对象

javascript - jquery 对话框小部件未传递我的表单值

javascript - 为 mocha 测试设置数据库连接的最佳实践和最有效的方法

go - 将oracle时间字符串转换为time.Time golang

java - 如何使用 JEE7 Websockets 将参数传递给 @OnOpen 方法,