Refactor: session remove duplicate ID in endpoints.

This commit is contained in:
Miroslav Šedivý 2020-10-31 23:53:19 +01:00
parent e150203b54
commit 5c92b75cf7
7 changed files with 53 additions and 80 deletions

View File

@ -1,8 +1,6 @@
package session package session
import ( import (
"fmt"
"github.com/kataras/go-events" "github.com/kataras/go-events"
"github.com/rs/zerolog" "github.com/rs/zerolog"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
@ -14,7 +12,7 @@ import (
func New(remote types.RemoteManager) *SessionManager { func New(remote types.RemoteManager) *SessionManager {
return &SessionManager{ return &SessionManager{
logger: log.With().Str("module", "session").Logger(), logger: log.With().Str("module", "session").Logger(),
host: "", host: nil,
remote: remote, remote: remote,
members: make(map[string]*Session), members: make(map[string]*Session),
emmiter: events.New(), emmiter: events.New(),
@ -23,7 +21,7 @@ func New(remote types.RemoteManager) *SessionManager {
type SessionManager struct { type SessionManager struct {
logger zerolog.Logger logger zerolog.Logger
host string host types.Session
remote types.RemoteManager remote types.RemoteManager
members map[string]*Session members map[string]*Session
emmiter events.EventEmmiter emmiter events.EventEmmiter
@ -50,31 +48,23 @@ func (manager *SessionManager) New(id string, admin bool, socket types.WebSocket
} }
func (manager *SessionManager) HasHost() bool { func (manager *SessionManager) HasHost() bool {
return manager.host != "" return manager.host != nil
} }
func (manager *SessionManager) SetHost(id string) error { func (manager *SessionManager) SetHost(host types.Session) {
host, ok := manager.GetHost() manager.host = host
if ok {
manager.host = id
manager.emmiter.Emit("host", host) manager.emmiter.Emit("host", host)
return nil
}
return fmt.Errorf("invalid session id %s", id)
} }
func (manager *SessionManager) GetHost() (types.Session, bool) { func (manager *SessionManager) GetHost() types.Session {
host, ok := manager.members[manager.host] return manager.host
return host, ok
} }
func (manager *SessionManager) ClearHost() { func (manager *SessionManager) ClearHost() {
host, ok := manager.GetHost() host := manager.host
manager.host = "" manager.host = nil
if ok {
manager.emmiter.Emit("host_cleared", host) manager.emmiter.Emit("host_cleared", host)
} }
}
func (manager *SessionManager) Has(id string) bool { func (manager *SessionManager) Has(id string) bool {
_, ok := manager.members[id] _, ok := manager.members[id]
@ -119,14 +109,14 @@ func (manager *SessionManager) Members() []*types.Member {
func (manager *SessionManager) Destroy(id string) error { func (manager *SessionManager) Destroy(id string) error {
session, ok := manager.members[id] session, ok := manager.members[id]
if ok { if ok {
delete(manager.members, id)
err := session.destroy() err := session.destroy()
if !manager.remote.Streaming() && len(manager.members) <= 0 { if !manager.remote.Streaming() && len(manager.members) <= 0 {
manager.remote.StopStream() manager.remote.StopStream()
} }
manager.emmiter.Emit("before_destroy", session) manager.emmiter.Emit("destroy", id)
delete(manager.members, id)
return err return err
} }
@ -164,9 +154,9 @@ func (manager *SessionManager) OnHostCleared(listener func(session types.Session
}) })
} }
func (manager *SessionManager) OnBeforeDestroy(listener func(session types.Session)) { func (manager *SessionManager) OnDestroy(listener func(id string)) {
manager.emmiter.On("before_destroy", func(payload ...interface{}) { manager.emmiter.On("destroy", func(payload ...interface{}) {
listener(payload[0].(*Session)) listener(payload[0].(string))
}) })
} }

View File

@ -37,7 +37,7 @@ func (session *Session) Muted() bool {
} }
func (session *Session) IsHost() bool { func (session *Session) IsHost() bool {
return session.manager.host == session.id return session.manager.host != nil && session.manager.host.ID() == session.ID()
} }
func (session *Session) Connected() bool { func (session *Session) Connected() bool {

View File

@ -29,8 +29,8 @@ type Session interface {
type SessionManager interface { type SessionManager interface {
New(id string, admin bool, socket WebSocket) Session New(id string, admin bool, socket WebSocket) Session
HasHost() bool HasHost() bool
SetHost(id string) error SetHost(Session)
GetHost() (Session, bool) GetHost() Session
ClearHost() ClearHost()
Has(id string) bool Has(id string) bool
Get(id string) (Session, bool) Get(id string) (Session, bool)
@ -40,7 +40,7 @@ type SessionManager interface {
Broadcast(v interface{}, exclude interface{}) error Broadcast(v interface{}, exclude interface{}) error
OnHost(listener func(session Session)) OnHost(listener func(session Session))
OnHostCleared(listener func(session Session)) OnHostCleared(listener func(session Session))
OnBeforeDestroy(listener func(session Session)) OnDestroy(listener func(id string))
OnCreated(listener func(session Session)) OnCreated(listener func(session Session))
OnConnected(listener func(session Session)) OnConnected(listener func(session Session))
} }

View File

@ -64,14 +64,10 @@ func (h *MessageHandler) adminControl(session types.Session) error {
return nil return nil
} }
host, ok := h.sessions.GetHost() host := h.sessions.GetHost()
h.sessions.SetHost(session)
if err := h.sessions.SetHost(session.ID()); err != nil { if host != nil {
h.logger.Warn().Err(err).Msgf("SetHost failed")
return err
}
if ok {
if err := h.sessions.Broadcast( if err := h.sessions.Broadcast(
message.AdminTarget{ message.AdminTarget{
Event: event.ADMIN_CONTROL, Event: event.ADMIN_CONTROL,
@ -101,11 +97,10 @@ func (h *MessageHandler) adminRelease(session types.Session) error {
return nil return nil
} }
host, ok := h.sessions.GetHost() host := h.sessions.GetHost()
h.sessions.ClearHost() h.sessions.ClearHost()
if ok { if host != nil {
if err := h.sessions.Broadcast( if err := h.sessions.Broadcast(
message.AdminTarget{ message.AdminTarget{
Event: event.ADMIN_RELEASE, Event: event.ADMIN_RELEASE,
@ -135,23 +130,21 @@ func (h *MessageHandler) adminGive(session types.Session, payload *message.Admin
return nil return nil
} }
if !h.sessions.Has(payload.ID) { target, ok := h.sessions.Get(payload.ID)
h.logger.Debug().Str("id", payload.ID).Msg("user does not exist") if !ok {
h.logger.Debug().Str("id", target.ID()).Msg("user does not exist")
return nil return nil
} }
// set host // set host
if err := h.sessions.SetHost(payload.ID); err != nil { h.sessions.SetHost(target)
h.logger.Warn().Err(err).Msgf("SetHost failed")
return err
}
// let everyone know // let everyone know
if err := h.sessions.Broadcast( if err := h.sessions.Broadcast(
message.AdminTarget{ message.AdminTarget{
Event: event.CONTROL_GIVE, Event: event.CONTROL_GIVE,
ID: session.ID(), ID: session.ID(),
Target: payload.ID, Target: target.ID(),
}, nil); err != nil { }, nil); err != nil {
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_LOCKED) h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_LOCKED)
return err return err

View File

@ -31,13 +31,11 @@ func (h *MessageHandler) controlRelease(session types.Session) error {
} }
func (h *MessageHandler) controlRequest(session types.Session) error { func (h *MessageHandler) controlRequest(session types.Session) error {
// check for host host := h.sessions.GetHost()
if !h.sessions.HasHost() {
if host == nil {
// set host // set host
if err := h.sessions.SetHost(session.ID()); err != nil { h.sessions.SetHost(session)
h.logger.Warn().Err(err).Msgf("SetHost failed")
return err
}
// let everyone know // let everyone know
if err := h.sessions.Broadcast( if err := h.sessions.Broadcast(
@ -48,14 +46,7 @@ func (h *MessageHandler) controlRequest(session types.Session) error {
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_LOCKED) h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_LOCKED)
return err return err
} }
} else {
return nil
}
// get host
host, ok := h.sessions.GetHost()
if ok {
// tell session there is a host // tell session there is a host
if err := session.Send(message.Control{ if err := session.Send(message.Control{
Event: event.CONTROL_REQUEST, Event: event.CONTROL_REQUEST,
@ -85,23 +76,21 @@ func (h *MessageHandler) controlGive(session types.Session, payload *message.Con
return nil return nil
} }
if !h.sessions.Has(payload.ID) { target, ok := h.sessions.Get(payload.ID)
h.logger.Debug().Str("id", payload.ID).Msg("user does not exist") if !ok {
h.logger.Debug().Str("id", target.ID()).Msg("user does not exist")
return nil return nil
} }
// set host // set host
if err := h.sessions.SetHost(payload.ID); err != nil { h.sessions.SetHost(target)
h.logger.Warn().Err(err).Msgf("SetHost failed")
return err
}
// let everyone know // let everyone know
if err := h.sessions.Broadcast( if err := h.sessions.Broadcast(
message.ControlTarget{ message.ControlTarget{
Event: event.CONTROL_GIVE, Event: event.CONTROL_GIVE,
ID: session.ID(), ID: session.ID(),
Target: payload.ID, Target: target.ID(),
}, nil); err != nil { }, nil); err != nil {
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_LOCKED) h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_LOCKED)
return err return err

View File

@ -43,8 +43,8 @@ func (h *MessageHandler) SessionConnected(session types.Session) error {
} }
// tell session there is a host // tell session there is a host
host, ok := h.sessions.GetHost() host := h.sessions.GetHost()
if ok { if host != nil {
if err := session.Send(message.Control{ if err := session.Send(message.Control{
Event: event.CONTROL_LOCKED, Event: event.CONTROL_LOCKED,
ID: host.ID(), ID: host.ID(),
@ -67,13 +67,14 @@ func (h *MessageHandler) SessionConnected(session types.Session) error {
return nil return nil
} }
func (h *MessageHandler) SessionDestroyed(session types.Session) error { func (h *MessageHandler) SessionDestroyed(id string) error {
// clear host if exists // clear host if exists
if session.IsHost() { host := h.sessions.GetHost()
if host != nil && host.ID() == id {
h.sessions.ClearHost() h.sessions.ClearHost()
if err := h.sessions.Broadcast(message.Control{ if err := h.sessions.Broadcast(message.Control{
Event: event.CONTROL_RELEASE, Event: event.CONTROL_RELEASE,
ID: session.ID(), ID: id,
}, nil); err != nil { }, nil); err != nil {
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_RELEASE) h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_RELEASE)
} }
@ -83,7 +84,7 @@ func (h *MessageHandler) SessionDestroyed(session types.Session) error {
if err := h.sessions.Broadcast( if err := h.sessions.Broadcast(
message.MemberDisconnected{ message.MemberDisconnected{
Event: event.MEMBER_DISCONNECTED, Event: event.MEMBER_DISCONNECTED,
ID: session.ID(), ID: id,
}, nil); err != nil { }, nil); err != nil {
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.MEMBER_DISCONNECTED) h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.MEMBER_DISCONNECTED)
return err return err

View File

@ -71,11 +71,11 @@ func (ws *WebSocketHandler) Start() {
} }
}) })
ws.sessions.OnBeforeDestroy(func(session types.Session) { ws.sessions.OnDestroy(func(id string) {
if err := ws.handler.SessionDestroyed(session); err != nil { if err := ws.handler.SessionDestroyed(id); err != nil {
ws.logger.Warn().Str("id", session.ID()).Err(err).Msg("session destroyed with and error") ws.logger.Warn().Str("id", id).Err(err).Msg("session destroyed with and error")
} else { } else {
ws.logger.Debug().Str("id", session.ID()).Msg("session destroyed") ws.logger.Debug().Str("id", id).Msg("session destroyed")
} }
}) })
@ -94,8 +94,8 @@ func (ws *WebSocketHandler) Start() {
if ws.sessions.HasHost() { if ws.sessions.HasHost() {
text := ws.remote.ReadClipboard() text := ws.remote.ReadClipboard()
if text != current { if text != current {
session, ok := ws.sessions.GetHost() session := ws.sessions.GetHost()
if ok { if session != nil {
if err := session.Send(message.Clipboard{ if err := session.Send(message.Clipboard{
Event: event.CONTROL_CLIPBOARD, Event: event.CONTROL_CLIPBOARD,
Text: text, Text: text,