This is a creation in Article, where the information may have evolved or changed.
Package Rtmpimport ("Bufio" Log "Github.com/cihub/seelog" "Net" "Runtime" "Sync" "Time") var shandler serverhandler = new ( Defaultserverhandler) func listenandserve (addr string) error {srv: = &server{addr:addr,readtimeout:time. Duration (time. Second *), Writetimeout:time. Duration (time. Second *), lock:new (sync. Mutex)}return srv. Listenandserve ()}type Server struct {Addr string//Listener address readtimeout time. Duration//Read timeout writetimeout time. Duration//write timeout lock *sync. Mutex}var Gstreamid = UInt32 (+) func gen_next_stream_id (Chunkid uint32) uint32 {gstreamid + 1return Gstreamid}func Newco NN (conn net. Conn, SRV *server) (c *rtmpnetconnection) {c = new (rtmpnetconnection) c.remoteaddr = Conn. Remoteaddr (). String () C.server = Srvc.readchunksize = Rtmp_default_chunk_sizec.writechunksize = Rtmp_default_chunk_ Sizec.createtime = time. Now () C.bandwidth = << 10c.conn = connc.br = Bufio. Newreader (conn) c.bw = Bufio. Newwriter (conn) c.buf = Bufio. Newreadwriter (c.br, C.BW) C.lock = new (sync. Mutex)//c.csid_chunk = Make (map[uint32]uint32) c.lastreadheaders = Make (map[uint32]*rtmpheader) C.lastwriteheaders = Make (map[uint32]*rtmpheader) c.incompletepackets = Make (map[uint32]payload) C.nextstreamid = GEN_NEXT_STREAM_ idc.objectencoding = 0return}func (P *server) Listenandserve () error {addr: = P.addrif Addr = = "" {addr = ": 1935"}l, err: = Net. Listen ("tcp", addr) if err! = Nil {return err}for I: = 0; I < runtime. Numcpu (); i++ {go P.loop (L)}return nil}func (SRV *server) loop (l net. Listener) Error {defer l.close () var tempdelay time. Duration//How long-to-sleep on accept failurefor {GRW, E: = L.accept () if E! = nil {if NE, ok: = E. (NET. ERROR); Ok && ne. Temporary () {if Tempdelay = = 0 {tempdelay = 5 * Time.millisecond} else {tempdelay *= 2}if max: = 1 * time. Second; Tempdelay > Max {tempdelay = Max}log. Errorf ("Rtmp:accept error:%v; Retrying in%v ", E, Tempdelay) time. Sleep (tempdelay) Continue}return E}tempdelay = 0go serve (SRV, GRW)}}func serve (SRV *server, con net. Conn) {Conn: = Newconn (Con, SRV) if!handshake1 (conn.buf) {Conn. Close () return}msg, err: = Readmessage (conn) if err! = Nil {log. Error ("Netconnecton read error", ERR) Conn. Close () return}cmd, OK: = Msg. (*connectmessage) if!ok | | Cmd.command! = "Connect" {log. Error ("Netconnecton Received Invalid connectmessage", MSG) Conn. Close () Return}conn.app = getString (cmd. Object, "app") conn.objectencoding = Int (getnumber (cmd). Object, "objectencoding")) log. Debug (cmd) err = sendackwinsize (conn, 512<<10) if err! = Nil {log. Error ("Netconnecton sendackwinsize error", ERR) Conn. Close () Return}err = Sendpeerbandwidth (conn, 512<<10) if err! = Nil {log. Error ("Netconnecton sendpeerbandwidth error", ERR) Conn. Close () Return}err = Sendstreambegin (conn) if err! = Nil {log. Error ("Netconnecton sendstreambegin error", ERR) Conn. Close () Return}err = sendconnectsuccess (conn) if err! = Nil {log. Error ("Netconnecton sendconnectsuccess error", ERR) Conn. Close () return}conn.connected = Truenewnetstream (conn, Shandler, nil). Serve ()}
Reprint Address: http://www.oschina.net/code/snippet_874_22821