func (v *Rtmp) serve(c net.Conn) { // use gfork to serve the connection. v.wc.GFork("", func(wc core.WorkerContainer) { defer func() { if r := recover(); r != nil { if !core.IsNormalQuit(r) { core.Warn.Println("rtmp ignore", r) } core.Error.Println(string(debug.Stack())) } }() core.Trace.Println("rtmp accept", c.RemoteAddr()) conn := protocol.NewRtmpConnection(c, v.wc) defer conn.Close() if err := v.cycle(conn); !core.IsNormalQuit(err) { core.Warn.Println("ignore error when cycle rtmp. err is", err) return } core.Info.Println("rtmp cycle ok.") return }) }
func (v *Rtmp) serve(c net.Conn) { // use gfork to serve the connection. v.wc.GFork("", func(wc core.WorkerContainer) { defer func() { if r := recover(); r != nil { if !core.IsNormalQuit(r) { core.Warn.Println("rtmp ignore", r) } core.Error.Println(string(debug.Stack())) } }() defer func() { if err := c.Close(); err != nil { core.Info.Println("ignore close failed. err is", err) } }() // for tcp connections. if c, ok := c.(*net.TCPConn); ok { // set TCP_NODELAY to false for performance issue. // TODO: FIXME: config it. // TODO: FIXME: refine for the realtime streaming. if err := c.SetNoDelay(false); err != nil { core.Error.Println("set TCP_NODELAY failed. err is", err) return } } core.Trace.Println("rtmp accept", c.RemoteAddr()) conn := protocol.NewRtmpConnection(c, v.wc) defer conn.Close() if err := v.cycle(conn); err != nil { if !core.IsNormalQuit(err) && !IsControlError(err) { core.Warn.Println("ignore error when cycle rtmp. err is", err) } else { core.Info.Println("rtmp cycle ok.") } return } return }) }