Go - Web 服务器在同一端口上侦听多个协议(HTTP 和 RTMP)

Go - Webserver listening for multiple protocols (HTTP and RTMP) on the same port

我正在尝试在 Go 中实现 RTMP 协议以配合我的 Web 应用程序,但是我似乎无法找到在同一端口上同时处理 HTTP 和 RTMP 的解决方案。

这个想法是这样的。

package main

import (
    "fmt"
    "io"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Hello!")
    })

    http.HandleFunc("/rtmp", func(w http.ResponseWriter, r *http.Request) {
        // RTMP handling here
    })

    fmt.Println("Starting web server")
    http.ListenAndServe(":8000", nil)
}

zhangpeihao/gortmp has a great RMTP module with an example that shows 通过侦听 TCP 套接字处理 RTMP。但是如何在特定端点而不是第二个端口上处理它?

虽然想要避免将 RTMPT 转换为 RTMP,并且不必分叉其他模块,但这是我最终通过读取第一个字节的解决方案。可以找到完整的实现 here.

func createLocalConnection(port string) *net.TCPConn {
    addr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:"+port)
    if err != nil {
        panic(err)
    }
    conn, err := net.DialTCP("tcp", nil, addr)
    if err != nil {
        panic(err)
    }
    return conn
}

func proxyConnection(conn *net.TCPConn) {
  defer conn.Close()
  data := make([]byte, 1)
  n, err := conn.Read(data)
  if err != nil {
    fmt.Println(err)
    return
  }

  var proxyConn *net.TCPConn
  if data[0] == 0x03 { // RTMP first byte.
    proxyConn = createLocalConnection(RTMPPort)
  } else {
    proxyConn = createLocalConnection(HTTPPort)
  }
  proxyConn.Write(data[:n])
  defer proxyConn.Close()

  // Request loop
  go func() {
    for {
      data := make([]byte, 1024*1024)
      n, err := conn.Read(data)
      if err != nil {
        break
      }
      proxyConn.Write(data[:n])
    }
  }()

  // Response loop
  for {
    data := make([]byte, 1024*1024)
    n, err := proxyConn.Read(data)
    if err != nil {
      break
    }
    conn.Write(data[:n])
  }
}

func main() {
  listener, err := net.ListenTCP("tcp", addr)
    if err != nil {
        panic(err)
    }

  for {
    conn, err := listener.AcceptTCP()
    if err != nil {
      fmt.Println(err)
      continue
    }

    go server.ProxyConnection(conn)
  }
}