【问题标题】:websocket client onmessage broken after refreshing browser刷新浏览器后websocket客户端onmessage中断
【发布时间】:2016-12-01 14:35:09
【问题描述】:

我有一个Websocket 服务器,用go 编写,包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。有关说明,请参阅 this question。多个输出 groutine 是否从 global.outgoingMessage 接收?如果是这样,如何确保将足够的消息发送到 global.outgoingMessage 以满足所有正在运行的输出 goroutine?
  • @MellowMarmot 你是对的。 global.outgoingMessage 仅在此处理程序内接收,但它是一个全局通道,因此当刷新浏览器 websocket 连接时,先前的连接仍在侦听通道。如果你发布答案,我会接受。谢谢!

标签: javascript go websocket


【解决方案1】:

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

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

旁白:应用程序泄漏了 goroutine。有关说明,请参阅 this question

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多