如何有效解码Gob并等待通过TCP连接到达的更多内容

I'd like to have a TCP connection for a gaming application. It's important to be time efficient. I want to receive many objects efficiently. It's also important to be CPU efficient because of the load.

So far, I can make sure handleConnection is called every time a connection is dialed using go's net library. However once the connection is created, I have to poll (check over and over again to see if new data is ready on the connection). This seems inefficient. I don't want to run that check to see if new data is ready if it's needlessly sucking up CPU.

I was looking for something such as the following two options but didn't find what I was looking for.

(1) Do a read operation that somehow blocks (without sucking CPU) and then unblocks when new stuff is ready on the connection stream. I could not find that.

(2) Do an async approach where a function is called when new data arrives on the connection stream (not just when a new connection is dialed). I could not find that.

I don't want to put any sleep calls in here because that will increase the latency of responding to singles messages.

I also considered dialing out for every single message, but I'm not sure if that's efficient or not.

So I came up with code below, but it's still doing a whole lot of checking for new data with the Decode(p) call, which does not seem optimal.

How can I do this more efficiently?

func handleConnection(conn net.Conn) {
        dec := gob.NewDecoder(conn)
        p := &P{}

        for {
                result := dec.Decode(p)
                if result != nil {
                        // do nothing
                } else {
                        fmt.Printf("Received : %+v", p)
                        fmt.Println("result", result, "
")
                }

        }

        conn.Close()
}

You say:

So I came up with code below, but it's still doing a whole lot of checking for new data with the Decode(p) call.

Why do you think that? The gob decoder will issue a Read to the conn and wait for it to return data before figuring out what it is and decoding it. This is a blocking operation, and will be handled asynchronously by the runtime behind the scenes. The goroutine will sleep until the appropriate io signal comes in. You should not have to do anything fancy to make that more performant.

You can trace this yourself in the code for decoder.Decode.

I think your code will work just fine. CPU will be idle until it receives more data.

Go is not node. Every api is "blocking" for the most part, but that is not as much as a problem as in other platforms. The runtime manages goroutines very efficiently and delegates appropriate signals to sleeping goroutines as needed.