golang:使用杜松子酒路由器服务 net.Conn

golang: serving net.Conn using a gin router

我有一个处理传入 TCP 连接的函数:

func Handle(conn net.Conn) error {
    // ...
}

另外,我有一个初始化的 gin 路由器,带有已实现的句柄:

router := gin.New()
router.GET(...)
router.POST(...)

router.Run(addr) 调用将在 addr 上启动单独的 HTTP 服务器。

在没有 运行 单独的 HTTP 服务器的情况下,是否有任何方法可以使用此路由器处理 Handle 函数内的传入连接?

创建一个 net.Listener 通过在频道上接收来接受连接的实现:

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 }

通过发送到频道处理连接:

func (l *listener) Handle(c net.Conn) error {
    l.ch <- c
    return nil
}

以下是将它们联系在一起的方法:

  • 创建侦听器:

      s := newListener(someAddr)
    
  • 照常配置 Gin 引擎。

      router := gin.New()
      router.GET(...)
      router.POST(...)
    
  • 运行 goroutine 中的 net/http 服务器使用通道侦听器和 Gin 引擎:

      err := http.Serve(s, router)
      if err != nil {
          // handle error
      }
    
  • 在您的调度代码中,调用 s.Handle(c) 将连接传递给 net/http 服务器,然后传递给 Gin 引擎。

对于那些有类似任务的人 - 使用单个路由器处理来自多个端口的 TCP 连接,这是我最终找到的解决方法。我没有 运行 在端口上连接 HTTP 服务器,而是 运行 使用 router.RunUnix(socketName) 的 UNIX 套接字。完整的解决方案包括三个步骤:

  1. 运行 使用 router.RunUnix(socketName)

    通过 UNIX 套接字侦听的 HTTP 服务器
  2. Handle 函数中读取来自连接的传入字节并将它们发送到套接字。之后,从套接字中读取HTTP响应并写入连接。

  3. 关闭连接。