【问题标题】:Go - Webserver listening for multiple protocols (HTTP and RTMP) on the same portGo - Web 服务器在同一端口上侦听多个协议(HTTP 和 RTMP)
【发布时间】:2016-10-31 03:04:48
【问题描述】:

我正在尝试在 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 有一个很棒的 RMTP 模块,an example that shows 通过侦听 TCP 套接字来处理 RTMP。但是如何在特定端点而不是第二个端口上处理它?

【问题讨论】:

  • 我猜你需要隧道RTMP over HTTP
  • 除了其他协议中的隧道协议外,每个端口服务多个协议是不寻常的。我想某些解决方案将涉及查看收到的前几个字节,直到您可以决定使用哪个处理程序。我从未见过这种尝试。

标签: go rtmp


【解决方案1】:

虽然想要避免将 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)
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    • 2019-01-03
    • 2017-03-30
    • 2021-10-14
    • 1970-01-01
    相关资源
    最近更新 更多