From 3a4dd41f75c7b1936a3fb81954f3f0b505157126 Mon Sep 17 00:00:00 2001
From: Zorglube <630192+zorglube@users.noreply.github.com>
Date: Sun, 14 Mar 2021 03:13:20 +0100
Subject: [PATCH 1/7] Stream Viewers minimal statistics.
---
chatclient.go | 11 +++++----
chatcommands.go | 4 +++-
handlers.go | 24 +++++++++++++++++--
stats.go | 63 +++++++++++++++++++++++++++++++++++++++++++------
4 files changed, 88 insertions(+), 14 deletions(-)
diff --git a/chatclient.go b/chatclient.go
index b843859..cfc6ac3 100644
--- a/chatclient.go
+++ b/chatclient.go
@@ -91,17 +91,20 @@ func (cl *Client) NewMsg(data common.ClientData) {
// because the /me command outputs to the messages
msg = addSpoilerTags(msg)
+ msgLen := len(msg)
+
// Don't send zero-length messages
- if len(msg) == 0 {
+ if msgLen == 0 {
return
}
if strings.HasPrefix(msg, "/") {
// is a command
- msg = msg[1:len(msg)]
+ msg = msg[1:msgLen]
fullcmd := strings.Split(msg, " ")
cmd := strings.ToLower(fullcmd[0])
- args := fullcmd[1:len(fullcmd)]
+ fullcmdLen := len(fullcmd)
+ args := fullcmd[1:fullcmdLen]
response, err := commands.RunCommand(cmd, args, cl)
if response != "" || err != nil {
@@ -136,7 +139,7 @@ func (cl *Client) NewMsg(data common.ClientData) {
}
// Trim long messages
- if len(msg) > 400 {
+ if msgLen > 400 {
msg = msg[0:400]
}
diff --git a/chatcommands.go b/chatcommands.go
index d7de741..0be866f 100644
--- a/chatcommands.go
+++ b/chatcommands.go
@@ -277,11 +277,13 @@ var commands = &CommandControl{
cl.belongsTo.clientsMtx.Unlock()
// Just print max users and time alive here
- return fmt.Sprintf("Current users in chat: %d
Max users in chat: %d
Server uptime: %s
Stream uptime: %s",
+ return fmt.Sprintf("Current users in chat: %d
Max users in chat: %d
Server uptime: %s
Stream uptime: %s
Viewers: %d
Max Viewers: %d",
users,
stats.getMaxUsers(),
time.Since(stats.start),
stats.getStreamLength(),
+ stats.getViewerCount(),
+ stats.getMaxViewerCount(),
), nil
},
},
diff --git a/handlers.go b/handlers.go
index 8b3ae68..91af63e 100644
--- a/handlers.go
+++ b/handlers.go
@@ -409,8 +409,10 @@ func handlePlay(conn *rtmp.Conn) {
}
func handleLive(w http.ResponseWriter, r *http.Request) {
+ uri := strings.Trim(r.URL.Path, "/")
+
l.RLock()
- ch := channels[strings.Trim(r.URL.Path, "/")]
+ ch := channels[uri]
l.RUnlock()
if ch != nil {
@@ -424,9 +426,14 @@ func handleLive(w http.ResponseWriter, r *http.Request) {
muxer := flv.NewMuxerWriteFlusher(writeFlusher{httpflusher: flusher, Writer: w})
cursor := ch.que.Latest()
+ ip := extractIp(r)
+ stats.addViewer(ip)
avutil.CopyFile(muxer, cursor)
+ stats.removeViewer(ip)
} else {
-
+ // Maybe HTTP_204 is better than HTTP_404
+ w.WriteHeader(http.StatusNoContent)
+ stats.resetViewers()
}
}
@@ -439,3 +446,16 @@ func handleDefault(w http.ResponseWriter, r *http.Request) {
handleIndexTemplate(w, r)
}
}
+
+func extractIp(r *http.Request) string {
+ ip := r.Host
+ f := r.Header.Get("Forwarded")
+ xff := r.Header.Get("X-Forwarded-For")
+ if !(xff == "") {
+ ip = xff
+ }
+ if !(f == "") {
+ ip = f
+ }
+ return ip
+}
diff --git a/stats.go b/stats.go
index 4fc8b26..755becb 100644
--- a/stats.go
+++ b/stats.go
@@ -8,18 +8,45 @@ import (
)
type streamStats struct {
- messageIn int
- messageOut int
- maxUsers int
- start time.Time
- mutex sync.Mutex
-
+ messageIn int
+ messageOut int
+ maxUsers int
+ start time.Time
+ mutex sync.Mutex
streamStart time.Time
streamLive bool // True if live
+ viewers map[string]string
+ maxViewers int
+}
+
+func (s *streamStats) addViewer(ip string) {
+ s.mutex.Lock()
+ s.viewers[ip] = ip
+ s.updateMaxViewers(len(s.viewers))
+ s.mutex.Unlock()
+
+ common.LogDebugf("Viewer connect from: %s\n", ip)
+}
+func (s *streamStats) removeViewer(ip string) {
+ s.mutex.Lock()
+ delete(s.viewers, ip)
+ s.mutex.Unlock()
+
+ common.LogDebugf("Viewer left from: %s\n", ip)
+}
+
+func (s *streamStats) updateMaxViewers(size int) {
+ if s.maxViewers < size {
+ s.maxViewers = size
+ }
+}
+
+func (s *streamStats) resetViewers() {
+ s.viewers = make(map[string]string)
}
func newStreamStats() streamStats {
- return streamStats{start: time.Now(), streamLive: false}
+ return streamStats{start: time.Now(), streamLive: false, viewers: make(map[string]string)}
}
func (s *streamStats) msgInInc() {
@@ -57,6 +84,7 @@ func (s *streamStats) Print() {
common.LogInfof("Messages Out: %d\n", s.messageOut)
common.LogInfof("Max users in chat: %d\n", s.maxUsers)
common.LogInfof("Total Time: %s\n", time.Since(s.start))
+ common.LogInfof("Max Stream Viewer: %d\n", s.maxViewers)
}
func (s *streamStats) startStream() {
@@ -83,3 +111,24 @@ func (s *streamStats) getStreamLength() time.Duration {
}
return time.Since(s.streamStart)
}
+
+func (s *streamStats) getViewerCount() int {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+
+ return len(s.viewers)
+}
+
+func (s *streamStats) getMaxViewerCount() int {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+
+ return s.maxViewers
+}
+
+func (s *streamStats) getViewers() map[string]string {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+
+ return s.viewers
+}
From 6947d87f9f1d03d340dc8f663138e1de104a7eed Mon Sep 17 00:00:00 2001
From: Zorglube <630192+zorglube@users.noreply.github.com>
Date: Sun, 14 Mar 2021 03:13:20 +0100
Subject: [PATCH 2/7] Stream Viewers minimal statistics.
---
chatclient.go | 11 +++++----
chatcommands.go | 4 +++-
handlers.go | 24 +++++++++++++++++--
stats.go | 63 +++++++++++++++++++++++++++++++++++++++++++------
4 files changed, 88 insertions(+), 14 deletions(-)
diff --git a/chatclient.go b/chatclient.go
index b843859..cfc6ac3 100644
--- a/chatclient.go
+++ b/chatclient.go
@@ -91,17 +91,20 @@ func (cl *Client) NewMsg(data common.ClientData) {
// because the /me command outputs to the messages
msg = addSpoilerTags(msg)
+ msgLen := len(msg)
+
// Don't send zero-length messages
- if len(msg) == 0 {
+ if msgLen == 0 {
return
}
if strings.HasPrefix(msg, "/") {
// is a command
- msg = msg[1:len(msg)]
+ msg = msg[1:msgLen]
fullcmd := strings.Split(msg, " ")
cmd := strings.ToLower(fullcmd[0])
- args := fullcmd[1:len(fullcmd)]
+ fullcmdLen := len(fullcmd)
+ args := fullcmd[1:fullcmdLen]
response, err := commands.RunCommand(cmd, args, cl)
if response != "" || err != nil {
@@ -136,7 +139,7 @@ func (cl *Client) NewMsg(data common.ClientData) {
}
// Trim long messages
- if len(msg) > 400 {
+ if msgLen > 400 {
msg = msg[0:400]
}
diff --git a/chatcommands.go b/chatcommands.go
index d7de741..0be866f 100644
--- a/chatcommands.go
+++ b/chatcommands.go
@@ -277,11 +277,13 @@ var commands = &CommandControl{
cl.belongsTo.clientsMtx.Unlock()
// Just print max users and time alive here
- return fmt.Sprintf("Current users in chat: %d
Max users in chat: %d
Server uptime: %s
Stream uptime: %s",
+ return fmt.Sprintf("Current users in chat: %d
Max users in chat: %d
Server uptime: %s
Stream uptime: %s
Viewers: %d
Max Viewers: %d",
users,
stats.getMaxUsers(),
time.Since(stats.start),
stats.getStreamLength(),
+ stats.getViewerCount(),
+ stats.getMaxViewerCount(),
), nil
},
},
diff --git a/handlers.go b/handlers.go
index 8b3ae68..91af63e 100644
--- a/handlers.go
+++ b/handlers.go
@@ -409,8 +409,10 @@ func handlePlay(conn *rtmp.Conn) {
}
func handleLive(w http.ResponseWriter, r *http.Request) {
+ uri := strings.Trim(r.URL.Path, "/")
+
l.RLock()
- ch := channels[strings.Trim(r.URL.Path, "/")]
+ ch := channels[uri]
l.RUnlock()
if ch != nil {
@@ -424,9 +426,14 @@ func handleLive(w http.ResponseWriter, r *http.Request) {
muxer := flv.NewMuxerWriteFlusher(writeFlusher{httpflusher: flusher, Writer: w})
cursor := ch.que.Latest()
+ ip := extractIp(r)
+ stats.addViewer(ip)
avutil.CopyFile(muxer, cursor)
+ stats.removeViewer(ip)
} else {
-
+ // Maybe HTTP_204 is better than HTTP_404
+ w.WriteHeader(http.StatusNoContent)
+ stats.resetViewers()
}
}
@@ -439,3 +446,16 @@ func handleDefault(w http.ResponseWriter, r *http.Request) {
handleIndexTemplate(w, r)
}
}
+
+func extractIp(r *http.Request) string {
+ ip := r.Host
+ f := r.Header.Get("Forwarded")
+ xff := r.Header.Get("X-Forwarded-For")
+ if !(xff == "") {
+ ip = xff
+ }
+ if !(f == "") {
+ ip = f
+ }
+ return ip
+}
diff --git a/stats.go b/stats.go
index 4fc8b26..755becb 100644
--- a/stats.go
+++ b/stats.go
@@ -8,18 +8,45 @@ import (
)
type streamStats struct {
- messageIn int
- messageOut int
- maxUsers int
- start time.Time
- mutex sync.Mutex
-
+ messageIn int
+ messageOut int
+ maxUsers int
+ start time.Time
+ mutex sync.Mutex
streamStart time.Time
streamLive bool // True if live
+ viewers map[string]string
+ maxViewers int
+}
+
+func (s *streamStats) addViewer(ip string) {
+ s.mutex.Lock()
+ s.viewers[ip] = ip
+ s.updateMaxViewers(len(s.viewers))
+ s.mutex.Unlock()
+
+ common.LogDebugf("Viewer connect from: %s\n", ip)
+}
+func (s *streamStats) removeViewer(ip string) {
+ s.mutex.Lock()
+ delete(s.viewers, ip)
+ s.mutex.Unlock()
+
+ common.LogDebugf("Viewer left from: %s\n", ip)
+}
+
+func (s *streamStats) updateMaxViewers(size int) {
+ if s.maxViewers < size {
+ s.maxViewers = size
+ }
+}
+
+func (s *streamStats) resetViewers() {
+ s.viewers = make(map[string]string)
}
func newStreamStats() streamStats {
- return streamStats{start: time.Now(), streamLive: false}
+ return streamStats{start: time.Now(), streamLive: false, viewers: make(map[string]string)}
}
func (s *streamStats) msgInInc() {
@@ -57,6 +84,7 @@ func (s *streamStats) Print() {
common.LogInfof("Messages Out: %d\n", s.messageOut)
common.LogInfof("Max users in chat: %d\n", s.maxUsers)
common.LogInfof("Total Time: %s\n", time.Since(s.start))
+ common.LogInfof("Max Stream Viewer: %d\n", s.maxViewers)
}
func (s *streamStats) startStream() {
@@ -83,3 +111,24 @@ func (s *streamStats) getStreamLength() time.Duration {
}
return time.Since(s.streamStart)
}
+
+func (s *streamStats) getViewerCount() int {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+
+ return len(s.viewers)
+}
+
+func (s *streamStats) getMaxViewerCount() int {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+
+ return s.maxViewers
+}
+
+func (s *streamStats) getViewers() map[string]string {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+
+ return s.viewers
+}
From 5a03e809ba0982a2ca828a4b92fe2b44bfe92ce8 Mon Sep 17 00:00:00 2001
From: Zorglube <630192+zorglube@users.noreply.github.com>
Date: Tue, 16 Mar 2021 22:43:55 +0100
Subject: [PATCH 3/7] Count the streams using the 'http' sessions instead of
the 'IP'.
---
common/utils.go | 18 ++++++++++++++++++
handlers.go | 25 +++++--------------------
stats.go | 38 ++++++++++++++++++++++----------------
3 files changed, 45 insertions(+), 36 deletions(-)
diff --git a/common/utils.go b/common/utils.go
index f84900c..dbb011b 100644
--- a/common/utils.go
+++ b/common/utils.go
@@ -3,6 +3,7 @@ package common
// Misc utils
import (
+ "net/http"
"os"
"path/filepath"
"regexp"
@@ -41,3 +42,20 @@ func Substr(input string, start int, length int) string {
return string(asRunes[start : start+length])
}
+
+// Return the value of "Forwarded" or "X-Forwarded-For",
+// if "Forwarded" & "X-Forwarded-For" are present then "Forwarded" value is returned.
+// Return "" if "Forwarded" and "X-Forwarded-For" are absent.
+func ExtractForwarded(r *http.Request) string {
+ f := r.Header.Get("Forwarded")
+ if f != "" {
+ return f
+ }
+
+ xff := r.Header.Get("X-Forwarded-For")
+ if xff != "" {
+ return xff
+ }
+
+ return ""
+}
diff --git a/handlers.go b/handlers.go
index 91af63e..0348dad 100644
--- a/handlers.go
+++ b/handlers.go
@@ -104,7 +104,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
Conn: conn,
// If the server is behind a reverse proxy (eg, Nginx), look
// for this header to get the real IP address of the client.
- forwardedFor: r.Header.Get("X-Forwarded-For"),
+ forwardedFor: common.ExtractForwarded(r), // r.Header.Get("X-Forwarded-For"),
}
go func() {
@@ -409,10 +409,8 @@ func handlePlay(conn *rtmp.Conn) {
}
func handleLive(w http.ResponseWriter, r *http.Request) {
- uri := strings.Trim(r.URL.Path, "/")
-
l.RLock()
- ch := channels[uri]
+ ch := channels[strings.Trim(r.URL.Path, "/")]
l.RUnlock()
if ch != nil {
@@ -426,10 +424,10 @@ func handleLive(w http.ResponseWriter, r *http.Request) {
muxer := flv.NewMuxerWriteFlusher(writeFlusher{httpflusher: flusher, Writer: w})
cursor := ch.que.Latest()
- ip := extractIp(r)
- stats.addViewer(ip)
+ session, _ := sstore.Get(r, "moviesession")
+ stats.addViewer(session)
avutil.CopyFile(muxer, cursor)
- stats.removeViewer(ip)
+ stats.removeViewer(session)
} else {
// Maybe HTTP_204 is better than HTTP_404
w.WriteHeader(http.StatusNoContent)
@@ -446,16 +444,3 @@ func handleDefault(w http.ResponseWriter, r *http.Request) {
handleIndexTemplate(w, r)
}
}
-
-func extractIp(r *http.Request) string {
- ip := r.Host
- f := r.Header.Get("Forwarded")
- xff := r.Header.Get("X-Forwarded-For")
- if !(xff == "") {
- ip = xff
- }
- if !(f == "") {
- ip = f
- }
- return ip
-}
diff --git a/stats.go b/stats.go
index 755becb..eb8507c 100644
--- a/stats.go
+++ b/stats.go
@@ -4,6 +4,7 @@ import (
"sync"
"time"
+ "github.com/gorilla/sessions"
"github.com/zorchenhimer/MovieNight/common"
)
@@ -15,24 +16,25 @@ type streamStats struct {
mutex sync.Mutex
streamStart time.Time
streamLive bool // True if live
- viewers map[string]string
+ viewers map[*sessions.Session]int
maxViewers int
}
-func (s *streamStats) addViewer(ip string) {
+func (s *streamStats) addViewer(session *sessions.Session) {
s.mutex.Lock()
- s.viewers[ip] = ip
- s.updateMaxViewers(len(s.viewers))
+ s.viewers[session] = len(s.viewers)
+ size := len(s.viewers)
+ s.updateMaxViewers(size)
s.mutex.Unlock()
- common.LogDebugf("Viewer connect from: %s\n", ip)
+ common.LogDebugf("[stats] %d viewer(s) connected\n", size)
}
-func (s *streamStats) removeViewer(ip string) {
+func (s *streamStats) removeViewer(session *sessions.Session) {
s.mutex.Lock()
- delete(s.viewers, ip)
+ delete(s.viewers, session)
s.mutex.Unlock()
- common.LogDebugf("Viewer left from: %s\n", ip)
+ common.LogDebugf("[stats] One viewer left the stream\n")
}
func (s *streamStats) updateMaxViewers(size int) {
@@ -42,11 +44,15 @@ func (s *streamStats) updateMaxViewers(size int) {
}
func (s *streamStats) resetViewers() {
- s.viewers = make(map[string]string)
+ s.viewers = sessionsMapNew()
+}
+
+func sessionsMapNew() map[*sessions.Session]int {
+ return make(map[*sessions.Session]int)
}
func newStreamStats() streamStats {
- return streamStats{start: time.Now(), streamLive: false, viewers: make(map[string]string)}
+ return streamStats{start: time.Now(), streamLive: false, viewers: sessionsMapNew()}
}
func (s *streamStats) msgInInc() {
@@ -80,11 +86,11 @@ func (s *streamStats) Print() {
s.mutex.Lock()
defer s.mutex.Unlock()
- common.LogInfof("Messages In: %d\n", s.messageIn)
- common.LogInfof("Messages Out: %d\n", s.messageOut)
- common.LogInfof("Max users in chat: %d\n", s.maxUsers)
- common.LogInfof("Total Time: %s\n", time.Since(s.start))
- common.LogInfof("Max Stream Viewer: %d\n", s.maxViewers)
+ common.LogInfof("[stats] Messages In: %d\n", s.messageIn)
+ common.LogInfof("[stats] Messages Out: %d\n", s.messageOut)
+ common.LogInfof("[stats] Max users in chat: %d\n", s.maxUsers)
+ common.LogInfof("[stats] Total Time: %s\n", time.Since(s.start))
+ common.LogInfof("[stats] Max Stream Viewer: %d\n", s.maxViewers)
}
func (s *streamStats) startStream() {
@@ -126,7 +132,7 @@ func (s *streamStats) getMaxViewerCount() int {
return s.maxViewers
}
-func (s *streamStats) getViewers() map[string]string {
+func (s *streamStats) getViewers() map[*sessions.Session]int {
s.mutex.Lock()
defer s.mutex.Unlock()
From afc9f19e36c6de5f826fa83d425a480b8262c262 Mon Sep 17 00:00:00 2001
From: Zorglube <630192+zorglube@users.noreply.github.com>
Date: Tue, 16 Mar 2021 22:43:55 +0100
Subject: [PATCH 4/7] Count the streams using the 'http' sessions instead of
the 'IP'.
---
common/utils.go | 18 ++++++++++++++++++
handlers.go | 25 +++++--------------------
stats.go | 38 ++++++++++++++++++++++----------------
3 files changed, 45 insertions(+), 36 deletions(-)
diff --git a/common/utils.go b/common/utils.go
index f84900c..dbb011b 100644
--- a/common/utils.go
+++ b/common/utils.go
@@ -3,6 +3,7 @@ package common
// Misc utils
import (
+ "net/http"
"os"
"path/filepath"
"regexp"
@@ -41,3 +42,20 @@ func Substr(input string, start int, length int) string {
return string(asRunes[start : start+length])
}
+
+// Return the value of "Forwarded" or "X-Forwarded-For",
+// if "Forwarded" & "X-Forwarded-For" are present then "Forwarded" value is returned.
+// Return "" if "Forwarded" and "X-Forwarded-For" are absent.
+func ExtractForwarded(r *http.Request) string {
+ f := r.Header.Get("Forwarded")
+ if f != "" {
+ return f
+ }
+
+ xff := r.Header.Get("X-Forwarded-For")
+ if xff != "" {
+ return xff
+ }
+
+ return ""
+}
diff --git a/handlers.go b/handlers.go
index 91af63e..7c5f31a 100644
--- a/handlers.go
+++ b/handlers.go
@@ -104,7 +104,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
Conn: conn,
// If the server is behind a reverse proxy (eg, Nginx), look
// for this header to get the real IP address of the client.
- forwardedFor: r.Header.Get("X-Forwarded-For"),
+ forwardedFor: common.ExtractForwarded(r),
}
go func() {
@@ -409,10 +409,8 @@ func handlePlay(conn *rtmp.Conn) {
}
func handleLive(w http.ResponseWriter, r *http.Request) {
- uri := strings.Trim(r.URL.Path, "/")
-
l.RLock()
- ch := channels[uri]
+ ch := channels[strings.Trim(r.URL.Path, "/")]
l.RUnlock()
if ch != nil {
@@ -426,10 +424,10 @@ func handleLive(w http.ResponseWriter, r *http.Request) {
muxer := flv.NewMuxerWriteFlusher(writeFlusher{httpflusher: flusher, Writer: w})
cursor := ch.que.Latest()
- ip := extractIp(r)
- stats.addViewer(ip)
+ session, _ := sstore.Get(r, "moviesession")
+ stats.addViewer(session)
avutil.CopyFile(muxer, cursor)
- stats.removeViewer(ip)
+ stats.removeViewer(session)
} else {
// Maybe HTTP_204 is better than HTTP_404
w.WriteHeader(http.StatusNoContent)
@@ -446,16 +444,3 @@ func handleDefault(w http.ResponseWriter, r *http.Request) {
handleIndexTemplate(w, r)
}
}
-
-func extractIp(r *http.Request) string {
- ip := r.Host
- f := r.Header.Get("Forwarded")
- xff := r.Header.Get("X-Forwarded-For")
- if !(xff == "") {
- ip = xff
- }
- if !(f == "") {
- ip = f
- }
- return ip
-}
diff --git a/stats.go b/stats.go
index 755becb..eb8507c 100644
--- a/stats.go
+++ b/stats.go
@@ -4,6 +4,7 @@ import (
"sync"
"time"
+ "github.com/gorilla/sessions"
"github.com/zorchenhimer/MovieNight/common"
)
@@ -15,24 +16,25 @@ type streamStats struct {
mutex sync.Mutex
streamStart time.Time
streamLive bool // True if live
- viewers map[string]string
+ viewers map[*sessions.Session]int
maxViewers int
}
-func (s *streamStats) addViewer(ip string) {
+func (s *streamStats) addViewer(session *sessions.Session) {
s.mutex.Lock()
- s.viewers[ip] = ip
- s.updateMaxViewers(len(s.viewers))
+ s.viewers[session] = len(s.viewers)
+ size := len(s.viewers)
+ s.updateMaxViewers(size)
s.mutex.Unlock()
- common.LogDebugf("Viewer connect from: %s\n", ip)
+ common.LogDebugf("[stats] %d viewer(s) connected\n", size)
}
-func (s *streamStats) removeViewer(ip string) {
+func (s *streamStats) removeViewer(session *sessions.Session) {
s.mutex.Lock()
- delete(s.viewers, ip)
+ delete(s.viewers, session)
s.mutex.Unlock()
- common.LogDebugf("Viewer left from: %s\n", ip)
+ common.LogDebugf("[stats] One viewer left the stream\n")
}
func (s *streamStats) updateMaxViewers(size int) {
@@ -42,11 +44,15 @@ func (s *streamStats) updateMaxViewers(size int) {
}
func (s *streamStats) resetViewers() {
- s.viewers = make(map[string]string)
+ s.viewers = sessionsMapNew()
+}
+
+func sessionsMapNew() map[*sessions.Session]int {
+ return make(map[*sessions.Session]int)
}
func newStreamStats() streamStats {
- return streamStats{start: time.Now(), streamLive: false, viewers: make(map[string]string)}
+ return streamStats{start: time.Now(), streamLive: false, viewers: sessionsMapNew()}
}
func (s *streamStats) msgInInc() {
@@ -80,11 +86,11 @@ func (s *streamStats) Print() {
s.mutex.Lock()
defer s.mutex.Unlock()
- common.LogInfof("Messages In: %d\n", s.messageIn)
- common.LogInfof("Messages Out: %d\n", s.messageOut)
- common.LogInfof("Max users in chat: %d\n", s.maxUsers)
- common.LogInfof("Total Time: %s\n", time.Since(s.start))
- common.LogInfof("Max Stream Viewer: %d\n", s.maxViewers)
+ common.LogInfof("[stats] Messages In: %d\n", s.messageIn)
+ common.LogInfof("[stats] Messages Out: %d\n", s.messageOut)
+ common.LogInfof("[stats] Max users in chat: %d\n", s.maxUsers)
+ common.LogInfof("[stats] Total Time: %s\n", time.Since(s.start))
+ common.LogInfof("[stats] Max Stream Viewer: %d\n", s.maxViewers)
}
func (s *streamStats) startStream() {
@@ -126,7 +132,7 @@ func (s *streamStats) getMaxViewerCount() int {
return s.maxViewers
}
-func (s *streamStats) getViewers() map[string]string {
+func (s *streamStats) getViewers() map[*sessions.Session]int {
s.mutex.Lock()
defer s.mutex.Unlock()
From 43d95a25ae6d5e59e7ece4d522913b2e7ec57a9b Mon Sep 17 00:00:00 2001
From: Zorglube <630192+zorglube@users.noreply.github.com>
Date: Wed, 17 Mar 2021 00:07:44 +0100
Subject: [PATCH 5/7] Finally found a way to correctly build on BSD, so remove
BSD specific Makefile.
---
Makefile | 46 ++++++++++++++++++++++++++++++++++++++++++--
Makefile.BSD | 12 ------------
make/Makefile.common | 42 ----------------------------------------
3 files changed, 44 insertions(+), 56 deletions(-)
delete mode 100644 Makefile.BSD
delete mode 100755 make/Makefile.common
diff --git a/Makefile b/Makefile
index cf476cd..d1d00a2 100644
--- a/Makefile
+++ b/Makefile
@@ -7,9 +7,51 @@
# goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows"
# goarchList = "386 amd64 amd64p32 arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32leppc s390 s390x sparc sparc64"
-include make/Makefile.common
# Windows needs the .exe extension.
ifeq ($(OS),Windows_NT)
-EXT=.exe
+EXT=.exe
endif
+
+TAGS=
+
+.PHONY: fmt vet get clean dev setdev test ServerMovieNight
+
+all: fmt vet test MovieNight static/main.wasm settings.json
+
+server: ServerMovieNight static/main.wasm
+
+ServerMovieNight: *.go common/*.go
+ GOOS=${TARGET} GOARCH=${ARCH} go$(GO_VERSION) build -o MovieNight $(TAGS)
+
+setdev:
+ $(eval export TAGS=-tags "dev")
+
+dev: setdev all
+
+MovieNight: *.go common/*.go
+ GOOS=${TARGET} GOARCH=${ARCH} go$(GO_VERSION) build -o MovieNight${EXT} $(TAGS)
+
+static/js/wasm_exec.js:
+ cp $$(go$(GO_VERSION) env GOROOT)/misc/wasm/wasm_exec.js $@
+
+static/main.wasm: static/js/wasm_exec.js wasm/*.go common/*.go
+ GOOS=js GOARCH=wasm go$(GO_VERSION) build -o $@ $(TAGS) wasm/*.go
+
+clean:
+ -rm MovieNight${EXT} ./static/main.wasm ./static/js/wasm_exec.js
+
+fmt:
+ gofmt -w .
+
+vet:
+ go$(GO_VERSION) vet $(TAGS) ./...
+ GOOS=js GOARCH=wasm go$(GO_VERSION) vet $(TAGS) ./...
+
+test:
+ go$(GO_VERSION) test $(TAGS) ./...
+
+# Do not put settings_example.json here as a prereq to avoid overwriting
+# the settings if the example is updated.
+settings.json:
+ cp settings_example.json settings.json
diff --git a/Makefile.BSD b/Makefile.BSD
deleted file mode 100644
index f49a3f2..0000000
--- a/Makefile.BSD
+++ /dev/null
@@ -1,12 +0,0 @@
-# If a different version of Go is installed (via `go get`) set the GO_VERSION
-# environment variable to that version. For example, setting it to "1.13.7"
-# will run `go1.13.7 build [...]` instead of `go build [...]`.
-#
-# For info on installing extra versions, see this page:
-# https://golang.org/doc/install#extra_versions
-
-# goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows"
-# goarchList = "386 amd64 amd64p32 arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32leppc s390 s390x sparc sparc64"
-include make/Makefile.common
-
-GOOS=freebsd
diff --git a/make/Makefile.common b/make/Makefile.common
deleted file mode 100755
index e179728..0000000
--- a/make/Makefile.common
+++ /dev/null
@@ -1,42 +0,0 @@
-TAGS=
-
-.PHONY: fmt vet get clean dev setdev test ServerMovieNight
-
-all: fmt vet test MovieNight static/main.wasm settings.json
-
-server: ServerMovieNight static/main.wasm
-
-ServerMovieNight: *.go common/*.go
- GOOS=${TARGET} GOARCH=${ARCH} go$(GO_VERSION) build -o MovieNight $(TAGS)
-
-setdev:
- $(eval export TAGS=-tags "dev")
-
-dev: setdev all
-
-MovieNight: *.go common/*.go
- GOOS=${TARGET} GOARCH=${ARCH} go$(GO_VERSION) build -o MovieNight${EXT} $(TAGS)
-
-static/js/wasm_exec.js:
- cp $$(go$(GO_VERSION) env GOROOT)/misc/wasm/wasm_exec.js $@
-
-static/main.wasm: static/js/wasm_exec.js wasm/*.go common/*.go
- GOOS=js GOARCH=wasm go$(GO_VERSION) build -o $@ $(TAGS) wasm/*.go
-
-clean:
- -rm MovieNight${EXT} ./static/main.wasm ./static/js/wasm_exec.js
-
-fmt:
- gofmt -w .
-
-vet:
- go$(GO_VERSION) vet $(TAGS) ./...
- GOOS=js GOARCH=wasm go$(GO_VERSION) vet $(TAGS) ./...
-
-test:
- go$(GO_VERSION) test $(TAGS) ./...
-
-# Do not put settings_example.json here as a prereq to avoid overwriting
-# the settings if the example is updated.
-settings.json:
- cp settings_example.json settings.json
From 2e45392f6896de5f66d1b80d6afc54c90b179849 Mon Sep 17 00:00:00 2001
From: Zorglube <630192+zorglube@users.noreply.github.com>
Date: Wed, 17 Mar 2021 00:07:44 +0100
Subject: [PATCH 6/7] Finally found a way to correctly build on BSD, so remove
BSD specific Makefile.
---
Makefile | 46 ++++++++++++++++++++++++++++++++++++++++++--
Makefile.BSD | 12 ------------
make/Makefile.common | 42 ----------------------------------------
readme.md | 4 ++--
4 files changed, 46 insertions(+), 58 deletions(-)
delete mode 100644 Makefile.BSD
delete mode 100755 make/Makefile.common
diff --git a/Makefile b/Makefile
index cf476cd..d1d00a2 100644
--- a/Makefile
+++ b/Makefile
@@ -7,9 +7,51 @@
# goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows"
# goarchList = "386 amd64 amd64p32 arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32leppc s390 s390x sparc sparc64"
-include make/Makefile.common
# Windows needs the .exe extension.
ifeq ($(OS),Windows_NT)
-EXT=.exe
+EXT=.exe
endif
+
+TAGS=
+
+.PHONY: fmt vet get clean dev setdev test ServerMovieNight
+
+all: fmt vet test MovieNight static/main.wasm settings.json
+
+server: ServerMovieNight static/main.wasm
+
+ServerMovieNight: *.go common/*.go
+ GOOS=${TARGET} GOARCH=${ARCH} go$(GO_VERSION) build -o MovieNight $(TAGS)
+
+setdev:
+ $(eval export TAGS=-tags "dev")
+
+dev: setdev all
+
+MovieNight: *.go common/*.go
+ GOOS=${TARGET} GOARCH=${ARCH} go$(GO_VERSION) build -o MovieNight${EXT} $(TAGS)
+
+static/js/wasm_exec.js:
+ cp $$(go$(GO_VERSION) env GOROOT)/misc/wasm/wasm_exec.js $@
+
+static/main.wasm: static/js/wasm_exec.js wasm/*.go common/*.go
+ GOOS=js GOARCH=wasm go$(GO_VERSION) build -o $@ $(TAGS) wasm/*.go
+
+clean:
+ -rm MovieNight${EXT} ./static/main.wasm ./static/js/wasm_exec.js
+
+fmt:
+ gofmt -w .
+
+vet:
+ go$(GO_VERSION) vet $(TAGS) ./...
+ GOOS=js GOARCH=wasm go$(GO_VERSION) vet $(TAGS) ./...
+
+test:
+ go$(GO_VERSION) test $(TAGS) ./...
+
+# Do not put settings_example.json here as a prereq to avoid overwriting
+# the settings if the example is updated.
+settings.json:
+ cp settings_example.json settings.json
diff --git a/Makefile.BSD b/Makefile.BSD
deleted file mode 100644
index f49a3f2..0000000
--- a/Makefile.BSD
+++ /dev/null
@@ -1,12 +0,0 @@
-# If a different version of Go is installed (via `go get`) set the GO_VERSION
-# environment variable to that version. For example, setting it to "1.13.7"
-# will run `go1.13.7 build [...]` instead of `go build [...]`.
-#
-# For info on installing extra versions, see this page:
-# https://golang.org/doc/install#extra_versions
-
-# goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows"
-# goarchList = "386 amd64 amd64p32 arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32leppc s390 s390x sparc sparc64"
-include make/Makefile.common
-
-GOOS=freebsd
diff --git a/make/Makefile.common b/make/Makefile.common
deleted file mode 100755
index e179728..0000000
--- a/make/Makefile.common
+++ /dev/null
@@ -1,42 +0,0 @@
-TAGS=
-
-.PHONY: fmt vet get clean dev setdev test ServerMovieNight
-
-all: fmt vet test MovieNight static/main.wasm settings.json
-
-server: ServerMovieNight static/main.wasm
-
-ServerMovieNight: *.go common/*.go
- GOOS=${TARGET} GOARCH=${ARCH} go$(GO_VERSION) build -o MovieNight $(TAGS)
-
-setdev:
- $(eval export TAGS=-tags "dev")
-
-dev: setdev all
-
-MovieNight: *.go common/*.go
- GOOS=${TARGET} GOARCH=${ARCH} go$(GO_VERSION) build -o MovieNight${EXT} $(TAGS)
-
-static/js/wasm_exec.js:
- cp $$(go$(GO_VERSION) env GOROOT)/misc/wasm/wasm_exec.js $@
-
-static/main.wasm: static/js/wasm_exec.js wasm/*.go common/*.go
- GOOS=js GOARCH=wasm go$(GO_VERSION) build -o $@ $(TAGS) wasm/*.go
-
-clean:
- -rm MovieNight${EXT} ./static/main.wasm ./static/js/wasm_exec.js
-
-fmt:
- gofmt -w .
-
-vet:
- go$(GO_VERSION) vet $(TAGS) ./...
- GOOS=js GOARCH=wasm go$(GO_VERSION) vet $(TAGS) ./...
-
-test:
- go$(GO_VERSION) test $(TAGS) ./...
-
-# Do not put settings_example.json here as a prereq to avoid overwriting
-# the settings if the example is updated.
-settings.json:
- cp settings_example.json settings.json
diff --git a/readme.md b/readme.md
index 868525d..0ccc7a4 100644
--- a/readme.md
+++ b/readme.md
@@ -38,14 +38,14 @@ You have to :
- download `git clone https://github.com/zorchenhimer/MovieNight`, go into the source directory `cd MovieNight`;
- choose your `TARGET` oneof "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows";
- choose your `ARCH` oneof "386 amd64 amd64p32 arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32leppc s390 s390x sparc sparc64";
-- build `make TARGET=windows ARCH=386`;
+- build `make TARGET=windows ARCH=386` (On BSD systems use `gmake`);
- and run `./MovieNight`;
Example :
```bash
$ git clone https://github.com/zorchenhimer/MovieNight
$ cd MovieNight
-$ make TARGET=windows ARCH=386
+$ (make|gmake) TARGET=windows ARCH=386
$ ./MovieNight
```
From efbb284eb8a1ce2fbf629538c37e5f64228d23a6 Mon Sep 17 00:00:00 2001
From: Zorglube <630192+zorglube@users.noreply.github.com>
Date: Sat, 20 Mar 2021 22:32:13 +0100
Subject: [PATCH 7/7] Zorch review, use `session.ID` to count running stream
---
handlers.go | 4 ++--
stats.go | 17 ++++++++---------
2 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/handlers.go b/handlers.go
index 7c5f31a..e98b225 100644
--- a/handlers.go
+++ b/handlers.go
@@ -425,9 +425,9 @@ func handleLive(w http.ResponseWriter, r *http.Request) {
cursor := ch.que.Latest()
session, _ := sstore.Get(r, "moviesession")
- stats.addViewer(session)
+ stats.addViewer(session.ID)
avutil.CopyFile(muxer, cursor)
- stats.removeViewer(session)
+ stats.removeViewer(session.ID)
} else {
// Maybe HTTP_204 is better than HTTP_404
w.WriteHeader(http.StatusNoContent)
diff --git a/stats.go b/stats.go
index eb8507c..fc67098 100644
--- a/stats.go
+++ b/stats.go
@@ -4,7 +4,6 @@ import (
"sync"
"time"
- "github.com/gorilla/sessions"
"github.com/zorchenhimer/MovieNight/common"
)
@@ -16,22 +15,22 @@ type streamStats struct {
mutex sync.Mutex
streamStart time.Time
streamLive bool // True if live
- viewers map[*sessions.Session]int
+ viewers map[string]int
maxViewers int
}
-func (s *streamStats) addViewer(session *sessions.Session) {
+func (s *streamStats) addViewer(id string) {
s.mutex.Lock()
- s.viewers[session] = len(s.viewers)
+ s.viewers[id] = len(s.viewers)
size := len(s.viewers)
s.updateMaxViewers(size)
s.mutex.Unlock()
common.LogDebugf("[stats] %d viewer(s) connected\n", size)
}
-func (s *streamStats) removeViewer(session *sessions.Session) {
+func (s *streamStats) removeViewer(id string) {
s.mutex.Lock()
- delete(s.viewers, session)
+ delete(s.viewers, id)
s.mutex.Unlock()
common.LogDebugf("[stats] One viewer left the stream\n")
@@ -47,8 +46,8 @@ func (s *streamStats) resetViewers() {
s.viewers = sessionsMapNew()
}
-func sessionsMapNew() map[*sessions.Session]int {
- return make(map[*sessions.Session]int)
+func sessionsMapNew() map[string]int {
+ return make(map[string]int)
}
func newStreamStats() streamStats {
@@ -132,7 +131,7 @@ func (s *streamStats) getMaxViewerCount() int {
return s.maxViewers
}
-func (s *streamStats) getViewers() map[*sessions.Session]int {
+func (s *streamStats) getViewers() map[string]int {
s.mutex.Lock()
defer s.mutex.Unlock()