【问题标题】:Gorilla websocket how to unmarshal binary data into JSON?Gorilla websocket如何将二进制数据解组为JSON?
【发布时间】:2018-11-07 05:03:47
【问题描述】:

我在关注大猩猩提供的chat example

我仍然可以解组发送的 json 数据。我应该在readPump() 中这样做吗:

func (c *ChatClient) readPump() {
    defer func() {
        c.hub.unregisterChan <- c
        c.conn.Close()
    }()
    c.conn.SetReadLimit(maxMessageSize)
    c.conn.SetReadDeadline(time.Now().Add(pongWait))
    c.conn.SetPongHandler(func(string) error { c.conn.SetReadDeadline(time.Now().Add(pongWait)); return nil })
    for {
        _, message, err := c.conn.ReadMessage()
        // =================MY CODE START=============
        var comment Comment
        err = c.conn.ReadJSON(comment)
        if err != nil {
            LogErr("readjson()", err)
            break
        }
        err = json.Unmarshal(message, comment)
        if err != nil {
            LogErr("readjson()", err)
            break
        }
        // =================MY CODE END=============

        if err != nil {
            if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
                LogErr("IsUnexpectedCloseError()", err)
            }
            break
        }
        message = bytes.TrimSpace(bytes.Replace(message, newline, space, -1))
        c.hub.broadcastChan <- message
    }
}

或在writePump()

func (c *ChatClient) writePump() {
    ticker := time.NewTicker(pingPeriod)
    defer func() {
        ticker.Stop()
        c.conn.Close()
    }()
    for {
        select {
        case message, ok := <-c.send:
            c.conn.SetWriteDeadline(time.Now().Add(writeWait))

            // CLOSE
            if !ok {
                c.conn.WriteMessage(websocket.CloseMessage, []byte{})
                return
            }

            w, err := c.conn.NextWriter(websocket.BinaryMessage)
            if err != nil {
                LogErr("c.conn.NextWriter", err)
                return
            }
            w.Write(message)

            // Add queued chat messages to the current websocket message.
            n := len(c.send)
            for i := 0; i < n; i++ {
                w.Write(newline)
                w.Write(<-c.send)
            }

            if err := w.Close(); err != nil {
                LogErr("w.Close()", err)
                return
            }
        case <-ticker.C:
            c.conn.SetWriteDeadline(time.Now().Add(writeWait))
            if err := c.conn.WriteMessage(websocket.PingMessage, nil); err != nil {
                LogErr("c.conn.WriteMessage()", err)
                return
            }
        }
    }
}

LogErr() 方法不打印任何消息。完全迷失在这里。

【问题讨论】:

    标签: go gorilla


    【解决方案1】:

    应用程序在循环的每次迭代中读取两条消息,并尝试将这两条消息解组到comment。只阅读一封邮件。

    应用程序错误地调用了ReadJSONUnmarshal,这些函数返回的错误解释了原因:应用程序正试图解组为非指针。

    应用程序还将消息的原始字节发送到通道。看起来它可能是您复制的任何内容的剩余部分,因此我将在其余答案中忽略它。

    这是固定循环:

    for {
        var comment Comment
        err = c.conn.ReadJSON(&comment)
        if err != nil {
            if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
                LogErr("IsUnexpectedCloseError()", err)
            }
            break
        }
        // Do something with comment
    }
    

    【讨论】:

    • 感谢@ThunderCat,当我将该代码放入 for now 连接时,只会在客户端触发 webSocket.onclose(),而不会在后端引发任何错误。我放了调试器,似乎没有输入那部分代码。 JS 中返回的 onClose 事件看起来 {code: 1006, composition: false, currentTarget: WebSocket {url: "ws://localhost:3001/chat", readyState: 3, eventPhase: 2, isTrusted: true, srcElement: WebSocket {url: "ws://localhost:3001/chat", readyState: 3, bufferedAmount: 0, onopen: null, onerror: null, target: WebSocket {url: "ws://localhost:3001/chat", readyState: 3,...}
    • 原始代码中对 c.conn.ReadJSON 和 json.Unmarshal 的调用返回错误,但您没有看到任何错误记录。您应该确认 LogErr 确实按预期工作。您还注意到该程序似乎没有在服务器上输入代码。也许客户端正在连接到不同的端点或完全不同的服务器。
    • 为什么这仅在我将 JSON 作为这样的字符串发送时才有效:webSocket.send(JSON.stringify(comment)) 如果我尝试 webSocket.send(comment) 它不起作用
    • webSocket.send(JSON.stringify(comment)) 以服务器期望的格式对评论进行编码。 webSocket.send(comment) 失败,因为参数不是 one of the allowed types
    猜你喜欢
    • 2017-02-05
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 2013-11-05
    • 2012-03-21
    相关资源
    最近更新 更多