I have a function that handles an incoming TCP connection:
func Handle(conn net.Conn) error {
// ...
}
Also, I have an initialized gin router with implemented handles:
router := gin.New()
router.GET(...)
router.POST(...)
The router.Run(addr)
call will start a separate HTTP server on the addr
.
Is there any way to handle incoming connections inside the Handle
function using this router without running a separate HTTP server?
CodePudding user response:
Create a net.Listener implementation that accepts connections by receiving on a channel:
type listener struct {
ch chan net.Conn
addr net.Addr
}
// newListener creates a channel listener. The addr argument
// is the listener's network address.
func newListener(addr net.Addr) *listener {
return &listener{
ch: make(chan net.Conn),
addr: addr,
}
}
func (l *listener) Accept() (net.Conn, error) {
c, ok := <-l.ch
if !ok {
return nil, errors.New("closed")
}
return c, nil
}
func (l *listener) Close() error { return nil }
func (l *listener) Addr() net.Addr { return l.addr }
Handle connections by sending to the channel:
func (l *listener) Handle(c net.Conn) error {
l.ch <- c
return nil
}
Here's how to tie it all together:
Create the listener:
s := newListener(someAddr)
Configure the Gin engine as usual.
router := gin.New() router.GET(...) router.POST(...)
Run the net/http server in a goroutine using the channel listener and the Gin engine:
err := http.Serve(s, router) if err != nil { // handle error }
In your dispatching code, call the
s.Handle(c)
to pass the connection to the net/http server and then on to the Gin engine.