FAQ
How to implement asynchronous recv data from tcp connection? For example I
have several connections, and I want to receive data from all of them. My
solution looks like this:
for {
             select {
             case sendTo := <-poll.sender:
                 if err := sendTo.GetSession().Send(sendTo.Packet); err !=
nil {
                     poll.errorStream <- err
                 }

             case visitor := <-poll.connector:
                 go poll.matrixPasswd(visitor)

             case err := <-poll.errorStream:
                 poll.handleError(err)
             case <-poll.shutdown:
                 return

             default:
                 poll.context.AsyncRecv()
             }
         }

AsyncRecv method:
func (gmap *anyMap) AsyncRecv() {
     gmap.users.ForEach(func(obj interface{}) {
         user := obj.(*gs.GameState)
         if user.OnRecv || user.Shutdown {
             return
         }
         go func() {
             user.OnRecv = true
             if packet, err := user.GetSession().Recv(); err == nil {
                 user.PacketHandler(packet)
             } else {
                 if err.Should_close {
                     user.Shutdown = true
                 }
                 gmap.pollError <- err
             }
             user.OnRecv = false
         }()
     })
}

This code works fine, but cpu load is too big, even with 1 connection. Is
there a better way to do this?
Maybe there are libraries that provide such functionality?

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Konstantin Khomoutov at May 19, 2016 at 6:08 pm

    On Thu, 19 May 2016 08:19:03 -0700 (PDT) Saske Uchiha wrote:

    How to implement asynchronous recv data from tcp connection? For
    example I have several connections, and I want to receive data from
    all of them. My solution looks like this:
    [...]

    But why?

    Go has network poller explicitly integrated with its runtime scheduler
    so you just spawn one goroutine per TCP connection and read from these
    connections using plain io.Read() and friends: as soon as the
    underlying read(2) syscall on the socket is about to be blocked waiting
    for data, the goroutine issued that call will be put to sleep and
    preempted; as soon as it has data available (reported by the network
    poller) the scheuler will awaken that goroutine and allow that I/O call
    to proceed.

    In other words, there's absolutely no reason to invent callback-driven
    spaghetti code solutions for what just works.

    This is sort of the whole point of concurrency in Go.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedMay 19, '16 at 5:27p
activeMay 19, '16 at 6:08p
posts2
users2
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase