Golang Websocket 自定义 JSON 消息

huangapple go评论145阅读模式
英文:

Golang Websocket Custom JSON Messages

问题

我正在尝试发送/接收自定义的JSON消息。有三种情况下JSON结构会发生变化,因此我有三个不同的结构体。我必须访问作为RawMessage发送的room字符串。我的问题是channel Broadcast应该是什么类型?

type Message struct {
	Type int64 `json:"type"`
	Msg  json.RawMessage
}
case m := <-r.Broadcast:
	// chan Broadcast应该是什么类型?
	// 如果m的类型是json.RawMessage,我应该在这里进行解组吗?
	connections := r.Clients[m.Room]
	for c := range connections {
		select {
		case c.send <- m:
		default:
			close(c.send)
			delete(connections, c)
			if len(connections) == 0 {
				delete(r.Clients, m.Room)
			}
		}
	}
for {
	msg := &Message{}
	err := c.conn.ReadJSON(&msg)
	// _, msg, err := c.conn.ReadMessage()
	if err != nil {
		if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
			log.Printf("error: %v", err)
		}
		break
	}

	if msg.Type == 0 {
		newVideo := &NewVideo{}
		if err = json.Unmarshal(msg.Msg, &newVideo); err != nil {
			fmt.Println(err)
		}
		Roomb.Broadcast <- msg.Msg // ??? 我应该发送RawMessage吗?
		online[msg.Room] = msg
	} else if msg.Type == 1 {
		if _, ok := online[msg.Room]; ok {
			online[msg.Room].Start = float64(time.Now().Unix() - online[msg.Room].Timestamp)
			c.send <- online[msg.Room]
		}
	} else if msg.Type == 2 {
		Roomb.Broadcast <- msg.Msg // ??? 我应该发送RawMessage吗?
	}
	fmt.Println(msg)
}
英文:

I'm trying to send/receive custom JSON messages. There are 3 cases in which the JSON struct changes, therefore I have 3 different structs. I have to access the room string which is sent as RawMessage. My question is what type should the channel Broadcast be?

type Message struct {
	Type int64 `json:&quot;type&quot;`
	Msg  json.RawMessage
}

Broadcast chan interface{} // ??? RawMessage or maybe interface

          case m := &lt;-r.Broadcast:
			// What type should chan Broadcast be?
            // If m is of type json.RawMessage should I deal with unmarshalling here?
			connections := r.Clients[m.Room] // 
			for c := range connections {
				select {
				case c.send &lt;- m:
				default:
					close(c.send)
					delete(connections, c)
					if len(connections) == 0 {
						delete(r.Clients, m.Room)
					}
				}
			}
for {
		msg := &amp;Message{}
		err := c.conn.ReadJSON(&amp;msg)
		// _, msg, err := c.conn.ReadMessage()
		if err != nil {
			if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
				log.Printf(&quot;error: %v&quot;, err)
			}
			break
		}

		if msg.Type == 0 {
			newVideo := &amp;NewVideo{}
			if err = json.Unmarshal(msg.Msg, &amp;newVideo); err != nil {
				fmt.Println(err)
			}
			Roomb.Broadcast &lt;- msg.Msg // ??? should i send the RawMessage
			online[msg.Room] = msg
		} else if msg.Type == 1 {
			if _, ok := online[msg.Room]; ok {
				online[msg.Room].Start = float64(time.Now().Unix() - online[msg.Room].Timestamp)
				c.send &lt;- online[msg.Room]
			}
		} else if msg.Type == 2 {
			Roomb.Broadcast &lt;- msg.Msg // ??? should i send the RawMessage
		}
		fmt.Println(msg)
	}

答案1

得分: 0

  1. msg之前删除"&"。msg已经是一个指针。这可能会引起问题。

  2. 你的问题不是很清楚。如果msg.Type定义了msg.Msg的类型,那么我建议你使用实际的消息类型来定义通道,解析msg.Msg,然后通过通道发送它。

英文:
  1. Remove the "&" before msg. msg is already a pointer. This may make problems.

  2. Your question is not very clear. If msg.Type defines what the msg.Msg is, then I recommend you make channels typed with the actual message type, parse the msg.Msg, then send it through the channel.

huangapple
  • 本文由 发表于 2019年6月11日 10:39:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/56535748.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定