panjf2000 / gnet

🚀 gnet is a high-performance, lightweight, non-blocking, event-driven networking framework written in pure Go.
https://gnet.host
Apache License 2.0
9.69k stars 1.04k forks source link

[Question]: Validate the approach of implementing persistent TCP connections. #568

Closed SarthakMakhija closed 7 months ago

SarthakMakhija commented 7 months ago

Actions I've taken before I'm here

Questions with details

I have to implement persistent TCP connections from a client to a server for a usecase. The messages received on the connections will be protobuf encoded messages.

Would you have any example of the same? Or, would you be able to provide feedback on the following code?

The example is created using a gnet example.

Code snippets (optional)

func (s *simpleServer) OnBoot(eng gnet.Engine) (action gnet.Action) {
    logging.Infof("running server on %s with multi-core=%t",
        fmt.Sprintf("%s://%s", s.network, s.addr), s.multicore)
    s.eng = eng
    return
}

func (s *simpleServer) OnOpen(c gnet.Conn) (out []byte, action gnet.Action) {
    c.SetContext(new(protocol.SimpleCodec)) //some form of codec.
    atomic.AddInt32(&s.connected, 1)
    return
}

func (s *simpleServer) OnClose(c gnet.Conn, err error) (action gnet.Action) {
    if err != nil {
        logging.Infof("error occurred on connection=%s, %v\n", c.RemoteAddr().String(), err)
    }
    disconnected := atomic.AddInt32(&s.disconnected, 1)
    connected := atomic.AddInt32(&s.connected, -1)
    if connected == 0 {
        logging.Infof("all %d connections are closed, shut it down", disconnected)
        action = gnet.Shutdown
    }
    return
}

func (s *simpleServer) OnTraffic(c gnet.Conn) (action gnet.Action) {
    codec := c.Context().(*protocol.SimpleCodec) //same codec that was set in `OnOpen`.
    var packets []Message //Assume Message is decoded from the byte slice received from gnet.Conn.
    for {
        data, err := codec.Decode(c)
        if err == protocol.ErrIncompletePacket {
            break
        }
        if err != nil {
            logging.Errorf("invalid packet: %v", err)
            return gnet.Close
        }
        packets = append(packets, data)
    }

        //launch goroutines to process the incoming packets, using a workerpool.
        //the goroutine(s) will write the response to the connection using c.AsyncWrite().
    return
}
panjf2000 commented 7 months ago

I think you should go ahead and finish your program, then run some tests on it. If you find some issues during testing, then you can open GitHub issues here. It makes more sense to diagnose a program with more concrete details or issues. If you only want to ask some general questions, please go to our discord channel.