doubi4435 2016-10-31 03:04
浏览 394
已采纳

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

I'm trying to implement the RTMP protocol to along side my web application in Go, however I can't seem to figure out solution to handle both HTTP and and RTMP on the same port.

The idea would be something such as this.

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 handling RTMP by listening on a TCP socket. However how can handle it on a specific endpoint rather then a second port?

  • 写回答

1条回答 默认 最新

  • douqin3245 2016-11-06 20:43
    关注

    While wanting to avoid having to convert RTMPT to RTMP, and without having to fork other modules, this was my solution in the end by reading the first byte. Full implementation can be found 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)
      }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用
  • ¥15 Web.config连不上数据库
  • ¥15 我想付费需要AKM公司DSP开发资料及相关开发。
  • ¥15 怎么配置广告联盟瀑布流
  • ¥15 Rstudio 保存代码闪退
  • ¥20 win系统的PYQT程序生成的数据如何放入云服务器阿里云window版?
  • ¥50 invest生境质量模块
  • ¥15 nhanes加权logistic回归,svyglm函数