package rtmp import ( "net" ) // meta-struct, holding together params for each streaing peer type ProtocolParams struct { peer_chunk_size uint32 chunk_size uint32 peer_ack_win uint32 curr_read uint32 stream_key string trans_id float64 } func NewServer(port string) (error) { l, err := net.Listen("tcp", ":" + port) if err != nil { return err } go start(l) return nil } func start(l net.Listener) { // bool to block connections while a stream is currently active // should have it on a per user basis instead, but adding a db // system would make this even more bloated stream_live := false for { conn, err := l.Accept() if err != nil { continue } else if stream_live { conn.Close() continue } stream_live = true go handle_conn(conn, &stream_live) } } func handle_conn(conn net.Conn, stream_live *bool) { defer conn.Close() defer func(a *bool) { *a = false }(stream_live) // flip the stream state back when done if !DoHandshake(conn) { return } chunk_wrapper := NewChunkWrapper(conn) if !NegotiateConnect(chunk_wrapper) { return } if !CreateStream(chunk_wrapper) { return } if !PublishAsKey(chunk_wrapper) { return } HandleDataLoop(chunk_wrapper) // no error handle since the connection ends either way go StreamCleanup(chunk_wrapper.params.stream_key, 60) // remove any media files left 1 min after stream ends }