server msgpack practise

156 views
Skip to first unread message

ZPL

unread,
Dec 8, 2015, 10:33:47 AM12/8/15
to golang-nuts
Hi list:

I'm now building a tcp server, use  https://github.com/ugorji/go to serilize/deserialize all messages between clients and server, I have some question on converting the decoded "interface" to correct types.

here's the example:

// client will send following 2 kinds of message to server
type HeartbeatMsg struct {
    Msgid int
    Seq   int
}

type LoginMsg struct {
    Msgid       int
    Username    string
    Password    string
}

// handle hearbeat msg
func handlHeartbeat(msg *HeartbeatMsg , conn net.Conn) {
    
}

// handle login msg
func handleLogin(msg *LoginMsg,conn net.Conn) {
    
}

func handleMsg(conn net.Conn) {
    var MsgpackHandle codec.MsgpackHandle
    // create a decoder for conn
    d := codec.NewDecoder(conn, &golib.MsgpackHandle)

    for {
        // use interface because we don't know what exactely client send to us
        var imsg interface{}
        err := d.Decode(&msg)

        // what can I do here to convert imsg to HeartbeatMsg or LoginMsg?
 
    }
}



Currently, I know there is Msgid of int at the begining of client message, I can access imsg with reflect to get that value, then make a deep copy of imsg to destination.
But there are cases that client messages don't share a COMMON HEADER, there should be a clean way to archive this.

Giulio Iotti

unread,
Dec 9, 2015, 7:25:18 AM12/9/15
to golang-nuts
On Tuesday, December 8, 2015 at 4:33:47 PM UTC+1, ZPL wrote:
Currently, I know there is Msgid of int at the begining of client message, I can access imsg with reflect to get that value, then make a deep copy of imsg to destination.
But there are cases that client messages don't share a COMMON HEADER, there should be a clean way to archive this.

The clean way is not to use reflection and make a real interface: https://play.golang.org/p/crVgeYVU6v

-- 
Giulio Iotti
 

刘志平

unread,
Dec 9, 2015, 8:28:42 AM12/9/15
to Giulio Iotti, golang-nuts
thanks Giulio, but it's different. 
In my case,  imsg is "pure" interface, not a reference to user defined struct, so I can't use type assert on imsg.

--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/YtyFfj6c0R8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
刘志平

MODCLOUD LU

unread,
Dec 9, 2015, 8:29:09 AM12/9/15
to Giulio Iotti, golang-nuts
sorry I used wrong email address to reply.
--
--刘志平

Konstantin Shaposhnikov

unread,
Dec 9, 2015, 8:36:12 AM12/9/15
to golang-nuts, dullg...@gmail.com
switch m := msg.(type) {
case HeartbeatMsg:
    // m is a HeartbeatMsg
case LoginMsg:
    // m is a LoginMsg
default:
    // m is some other type that we didn't name.
}

MODCLOUD LU

unread,
Dec 9, 2015, 9:02:38 AM12/9/15
to Konstantin Shaposhnikov, golang-nuts, Giulio Iotti
Sorry I didn't make it clear, This question is related to msgpack seriliazation, here:

Take the example again:

var MsgpackHandle codec.MsgpackHandle
d := codec.NewDecoder(conn, MsgpackHandle)
var msg interface{}
d.Decode(&msg)
logger.Info("type name:%s", reflect.ValueOf(msg).Kind())

It will print "slice" NOT "struct". so I can't do type assertion.

--刘志平

Giulio Iotti

unread,
Dec 9, 2015, 10:56:54 AM12/9/15
to golang-nuts, k.shapo...@gmail.com, dullg...@gmail.com
On Wednesday, December 9, 2015 at 4:02:38 PM UTC+2, ZPL wrote:
It will print "slice" NOT "struct". so I can't do type assertion.

Then you have a slice of interface{} that you can use the type switch on:

ms := msg.([]interface{})
for _, m := range ms {
    // type switch as shown above...

-- 
Giulio Iotti

Konstantin Shaposhnikov

unread,
Dec 9, 2015, 11:08:45 AM12/9/15
to golang-nuts, k.shapo...@gmail.com, dullg...@gmail.com
Correct me if I am wrong but I beleive that msgpack doesn't encode the type of the struct that you send. You will have to do send it together with the message. But instead of re-implementing RPC protocol yourself maybe you can use an existing one, such as grpc?

ZP L

unread,
Dec 9, 2015, 7:50:06 PM12/9/15
to Giulio Iotti, golang-nuts, Konstantin Shaposhnikov
yes, this might solve my problem, I'll try later!

--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/YtyFfj6c0R8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
--刘志平

ZP L

unread,
Dec 9, 2015, 7:56:57 PM12/9/15
to Konstantin Shaposhnikov, golang-nuts, Giulio Iotti
yes. msgpack doesn't encode the type of struct, and for some reason, my server is not using RPC, but RPC seems to be a right choice.
Reply all
Reply to author
Forward
0 new messages