|
|
@ -15,6 +15,7 @@ import ( |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
var l = &sync.RWMutex{} |
|
|
|
var l = &sync.RWMutex{} |
|
|
|
|
|
|
|
var _activeViewerPurgeTimeout = time.Second * 10 |
|
|
|
|
|
|
|
|
|
|
|
func setupStats() error { |
|
|
|
func setupStats() error { |
|
|
|
s := getSavedStats() |
|
|
|
s := getSavedStats() |
|
|
@ -29,6 +30,13 @@ func setupStats() error { |
|
|
|
} |
|
|
|
} |
|
|
|
}() |
|
|
|
}() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
viewerCountPruneTimer := time.NewTicker(5 * time.Second) |
|
|
|
|
|
|
|
go func() { |
|
|
|
|
|
|
|
for range viewerCountPruneTimer.C { |
|
|
|
|
|
|
|
pruneViewerCount() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}() |
|
|
|
|
|
|
|
|
|
|
|
return nil |
|
|
|
return nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -49,46 +57,40 @@ func IsStreamConnected() bool { |
|
|
|
return _stats.StreamConnected |
|
|
|
return _stats.StreamConnected |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// SetClientActive sets a client as active and connected.
|
|
|
|
// SetChatClientActive sets a client as active and connected.
|
|
|
|
func SetClientActive(client models.Client) { |
|
|
|
func SetChatClientActive(client models.Client) { |
|
|
|
l.Lock() |
|
|
|
l.Lock() |
|
|
|
defer l.Unlock() |
|
|
|
defer l.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
// If this clientID already exists then update it.
|
|
|
|
// If this clientID already exists then update it.
|
|
|
|
// Otherwise set a new one.
|
|
|
|
// Otherwise set a new one.
|
|
|
|
if existingClient, ok := _stats.Clients[client.ClientID]; ok { |
|
|
|
if existingClient, ok := _stats.ChatClients[client.ClientID]; ok { |
|
|
|
existingClient.LastSeen = time.Now() |
|
|
|
existingClient.LastSeen = time.Now() |
|
|
|
existingClient.Username = client.Username |
|
|
|
existingClient.Username = client.Username |
|
|
|
existingClient.MessageCount = client.MessageCount |
|
|
|
existingClient.MessageCount = client.MessageCount |
|
|
|
existingClient.Geo = geoip.GetGeoFromIP(existingClient.IPAddress) |
|
|
|
existingClient.Geo = geoip.GetGeoFromIP(existingClient.IPAddress) |
|
|
|
_stats.Clients[client.ClientID] = existingClient |
|
|
|
_stats.ChatClients[client.ClientID] = existingClient |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if client.Geo == nil { |
|
|
|
if client.Geo == nil { |
|
|
|
geoip.FetchGeoForIP(client.IPAddress) |
|
|
|
geoip.FetchGeoForIP(client.IPAddress) |
|
|
|
} |
|
|
|
} |
|
|
|
_stats.Clients[client.ClientID] = client |
|
|
|
_stats.ChatClients[client.ClientID] = client |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Don't update viewer counts if a live stream session is not active.
|
|
|
|
|
|
|
|
if _stats.StreamConnected { |
|
|
|
|
|
|
|
_stats.SessionMaxViewerCount = int(math.Max(float64(len(_stats.Clients)), float64(_stats.SessionMaxViewerCount))) |
|
|
|
|
|
|
|
_stats.OverallMaxViewerCount = int(math.Max(float64(_stats.SessionMaxViewerCount), float64(_stats.OverallMaxViewerCount))) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// RemoveClient removes a client from the active clients record.
|
|
|
|
// RemoveChatClient removes a client from the active clients record.
|
|
|
|
func RemoveClient(clientID string) { |
|
|
|
func RemoveChatClient(clientID string) { |
|
|
|
log.Trace("Removing the client:", clientID) |
|
|
|
log.Trace("Removing the client:", clientID) |
|
|
|
|
|
|
|
|
|
|
|
l.Lock() |
|
|
|
l.Lock() |
|
|
|
delete(_stats.Clients, clientID) |
|
|
|
delete(_stats.ChatClients, clientID) |
|
|
|
l.Unlock() |
|
|
|
l.Unlock() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func GetClients() []models.Client { |
|
|
|
func GetChatClients() []models.Client { |
|
|
|
l.RLock() |
|
|
|
l.RLock() |
|
|
|
clients := make([]models.Client, 0) |
|
|
|
clients := make([]models.Client, 0) |
|
|
|
for _, client := range _stats.Clients { |
|
|
|
for _, client := range _stats.ChatClients { |
|
|
|
chatClient := chat.GetClient(client.ClientID) |
|
|
|
chatClient := chat.GetClient(client.ClientID) |
|
|
|
if chatClient != nil { |
|
|
|
if chatClient != nil { |
|
|
|
clients = append(clients, chatClient.GetViewerClientFromChatClient()) |
|
|
|
clients = append(clients, chatClient.GetViewerClientFromChatClient()) |
|
|
@ -101,6 +103,33 @@ func GetClients() []models.Client { |
|
|
|
return clients |
|
|
|
return clients |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// SetViewerIdActive sets a client as active and connected.
|
|
|
|
|
|
|
|
func SetViewerIdActive(id string) { |
|
|
|
|
|
|
|
l.Lock() |
|
|
|
|
|
|
|
defer l.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_stats.Viewers[id] = time.Now() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Don't update viewer counts if a live stream session is not active.
|
|
|
|
|
|
|
|
if _stats.StreamConnected { |
|
|
|
|
|
|
|
_stats.SessionMaxViewerCount = int(math.Max(float64(len(_stats.Viewers)), float64(_stats.SessionMaxViewerCount))) |
|
|
|
|
|
|
|
_stats.OverallMaxViewerCount = int(math.Max(float64(_stats.SessionMaxViewerCount), float64(_stats.OverallMaxViewerCount))) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func pruneViewerCount() { |
|
|
|
|
|
|
|
viewers := make(map[string]time.Time) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for viewerId := range _stats.Viewers { |
|
|
|
|
|
|
|
viewerLastSeenTime := _stats.Viewers[viewerId] |
|
|
|
|
|
|
|
if time.Since(viewerLastSeenTime) < _activeViewerPurgeTimeout { |
|
|
|
|
|
|
|
viewers[viewerId] = viewerLastSeenTime |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_stats.Viewers = viewers |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func saveStats() error { |
|
|
|
func saveStats() error { |
|
|
|
if err := data.SetPeakOverallViewerCount(_stats.OverallMaxViewerCount); err != nil { |
|
|
|
if err := data.SetPeakOverallViewerCount(_stats.OverallMaxViewerCount); err != nil { |
|
|
|
log.Errorln("error saving viewer count", err) |
|
|
|
log.Errorln("error saving viewer count", err) |
|
|
@ -118,7 +147,8 @@ func saveStats() error { |
|
|
|
func getSavedStats() models.Stats { |
|
|
|
func getSavedStats() models.Stats { |
|
|
|
savedLastDisconnectTime, savedLastDisconnectTimeErr := data.GetLastDisconnectTime() |
|
|
|
savedLastDisconnectTime, savedLastDisconnectTimeErr := data.GetLastDisconnectTime() |
|
|
|
result := models.Stats{ |
|
|
|
result := models.Stats{ |
|
|
|
Clients: make(map[string]models.Client), |
|
|
|
ChatClients: make(map[string]models.Client), |
|
|
|
|
|
|
|
Viewers: make(map[string]time.Time), |
|
|
|
SessionMaxViewerCount: data.GetPeakSessionViewerCount(), |
|
|
|
SessionMaxViewerCount: data.GetPeakSessionViewerCount(), |
|
|
|
OverallMaxViewerCount: data.GetPeakOverallViewerCount(), |
|
|
|
OverallMaxViewerCount: data.GetPeakOverallViewerCount(), |
|
|
|
LastDisconnectTime: utils.NullTime{Time: savedLastDisconnectTime, Valid: savedLastDisconnectTimeErr == nil}, |
|
|
|
LastDisconnectTime: utils.NullTime{Time: savedLastDisconnectTime, Valid: savedLastDisconnectTimeErr == nil}, |
|
|
|