Gorilla Websocket如何将二进制数据解组为JSON?

I'm following the chat example provided by gorilla.

I still can get to unmarshal the json data sent. Should I do this in the 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
    }
}

or in the 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
            }
        }
    }
}

The LogErr() methods don't print any message. Totally lost here.

The application reads two messages on each iteration through the loop and attempts to unmarshal both to comment. Read one message only.

The application calls ReadJSON and Unmarshal incorrectly and the error returned from these functions explains why: the application is attempting to unmarshal to a non-pointer.

The application also sends the raw bytes of the message to a channel. That looks like it might be a leftover from whatever you are copying, so I'll ignore that in the remainder of the answer.

Here's the fixed loop:

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
}