Go websocket 序列化/反序列化 JSON

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

Go websocket serialization/deserialization json

问题

我正在使用golang的websocket库gorilla,并计划使用json进行序列化/反序列化。

假设我有以下结构体来接收传入的消息:

type Foo struct {
    A string `json:"a"`
    B string `json:"b"`
}

type Bar struct {
    C string `json:"c"`
    D string `json:"d"`
}

gorilla提供了conn.ReadJSON方法来接收传入的消息。传入的消息可以是Foo或Bar,但我不能使用conn.ReadJSON(Foo)并监听其他conn.ReadJSON(Bar),这会很混乱。我希望像JavaScript中的JSON.parse()一样,只使用conn.ReadJSON(Messages)。如何处理传入的消息:如果接收到Foo,则存储到Foo结构体中;如果接收到Bar,则存储到Bar结构体中?

我考虑使用以下结构体来解决问题:

type Messages struct {
    Control string `json:"control"`
    X       json.RawMessage
}

现在传入的消息有一个json控制字段,控制字段的值可以是Foo或Bar。使用if else语句,如果control等于Foo,则将X赋值给Foo;否则将X赋值给Bar。但是我无法确定X的数据类型。

欢迎提供任何解决方案,谢谢。

英文:

I'm using gorilla websocket, and i'm planing using json for serialization/deserialization.

Let say i have struct like this for receive the incoming messages:

type Foo struct {
    A string `json:"a"`
    B string `json:"b"`
}

and

type Bar struct {
    C string `json:"c"`
    D string `json:"d"`
}

gorilla provide conn.ReadJSON for receive incoming messages. The incoming messages can be Foo or Bar but i can't use conn.ReadJSON(Foo) and listen for other conn.ReadJSON(Bar), it's a mess. I want something like just conn.ReadJSON(Messages), like JSON.parse() in javascript. How to handle incoming messages if Foo is received, then it stored into Foo struct, and if Bar is received then it stored into Bar struct ?

I'm thingking the solution is using this struct:

type Messages struct {
    Control string `json:"control"`
    X // Data type for either Foo or Bar struct
}

The incoming messages now have json control, value of control can be Foo or Bar. Using if else if control==Foo then X is assign to Foo, else X is assign to Bar. But i can't figured the data type for X.

Any sollution is welcome, thankyou.

答案1

得分: 4

使用RawMessage

type Messages struct {
  Control string `json:"control"`
  X json.RawMessage
}

var m Messages
err := c.ReadJSON(&m)
if err != nil {
    // 处理错误
}
switch m.Control {
case "Foo":
    var foo Foo
    if err := json.Unmarshal([]byte(m.X), &foo); err != nil {
       // 处理错误
    }
    // 使用 foo 做一些操作

case "Bar":
   ... 按照 Foo 的模式处理

}
英文:

Use RawMessage.

type Messages struct {
  Control string `json:"control"`
  X json.RawMessage
}

var m Messages
err := c.ReadJSON(&m)
if err != nil {
    // handle error
}
switch m.Control {
case "Foo":
    var foo Foo
    if err := json.Unmarshal([]byte(m.X), &foo); err != nil {
       // handle error
    }
    // do something with foo

case "Bar":
   ... follow pattern for Foo

}

huangapple
  • 本文由 发表于 2016年12月13日 08:32:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/41111932.html
匿名

发表评论

匿名网友

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

确定