mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
add session to host change.
This commit is contained in:
parent
b562c797b3
commit
416faa3df4
@ -43,7 +43,7 @@ func (h *RoomHandler) controlRequest(w http.ResponseWriter, r *http.Request) err
|
|||||||
return utils.HttpForbidden("controls are locked")
|
return utils.HttpForbidden("controls are locked")
|
||||||
}
|
}
|
||||||
|
|
||||||
h.sessions.SetHost(session)
|
session.SetAsHost()
|
||||||
|
|
||||||
return utils.HttpSuccess(w)
|
return utils.HttpSuccess(w)
|
||||||
}
|
}
|
||||||
@ -55,19 +55,20 @@ func (h *RoomHandler) controlRelease(w http.ResponseWriter, r *http.Request) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
h.desktop.ResetKeys()
|
h.desktop.ResetKeys()
|
||||||
h.sessions.ClearHost()
|
session.ClearHost()
|
||||||
|
|
||||||
return utils.HttpSuccess(w)
|
return utils.HttpSuccess(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *RoomHandler) controlTake(w http.ResponseWriter, r *http.Request) error {
|
func (h *RoomHandler) controlTake(w http.ResponseWriter, r *http.Request) error {
|
||||||
session, _ := auth.GetSession(r)
|
session, _ := auth.GetSession(r)
|
||||||
h.sessions.SetHost(session)
|
session.SetAsHost()
|
||||||
|
|
||||||
return utils.HttpSuccess(w)
|
return utils.HttpSuccess(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *RoomHandler) controlGive(w http.ResponseWriter, r *http.Request) error {
|
func (h *RoomHandler) controlGive(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
session, _ := auth.GetSession(r)
|
||||||
sessionId := chi.URLParam(r, "sessionId")
|
sessionId := chi.URLParam(r, "sessionId")
|
||||||
|
|
||||||
target, ok := h.sessions.Get(sessionId)
|
target, ok := h.sessions.Get(sessionId)
|
||||||
@ -79,17 +80,18 @@ func (h *RoomHandler) controlGive(w http.ResponseWriter, r *http.Request) error
|
|||||||
return utils.HttpBadRequest("target session is not allowed to host")
|
return utils.HttpBadRequest("target session is not allowed to host")
|
||||||
}
|
}
|
||||||
|
|
||||||
h.sessions.SetHost(target)
|
target.SetAsHostBy(session)
|
||||||
|
|
||||||
return utils.HttpSuccess(w)
|
return utils.HttpSuccess(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *RoomHandler) controlReset(w http.ResponseWriter, r *http.Request) error {
|
func (h *RoomHandler) controlReset(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
session, _ := auth.GetSession(r)
|
||||||
_, hasHost := h.sessions.GetHost()
|
_, hasHost := h.sessions.GetHost()
|
||||||
|
|
||||||
if hasHost {
|
if hasHost {
|
||||||
h.desktop.ResetKeys()
|
h.desktop.ResetKeys()
|
||||||
h.sessions.ClearHost()
|
session.ClearHost()
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.HttpSuccess(w)
|
return utils.HttpSuccess(w)
|
||||||
|
@ -210,14 +210,14 @@ func (manager *SessionManagerCtx) Range(f func(session types.Session) bool) {
|
|||||||
// host
|
// host
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
func (manager *SessionManagerCtx) SetHost(host types.Session) {
|
func (manager *SessionManagerCtx) setHost(session, host types.Session) {
|
||||||
var hostId string
|
var hostId string
|
||||||
if host != nil {
|
if host != nil {
|
||||||
hostId = host.ID()
|
hostId = host.ID()
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.hostId.Store(hostId)
|
manager.hostId.Store(hostId)
|
||||||
manager.emmiter.Emit("host_changed", host)
|
manager.emmiter.Emit("host_changed", session, host)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *SessionManagerCtx) GetHost() (types.Session, bool) {
|
func (manager *SessionManagerCtx) GetHost() (types.Session, bool) {
|
||||||
@ -229,10 +229,6 @@ func (manager *SessionManagerCtx) GetHost() (types.Session, bool) {
|
|||||||
return manager.Get(hostId)
|
return manager.Get(hostId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *SessionManagerCtx) ClearHost() {
|
|
||||||
manager.SetHost(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (manager *SessionManagerCtx) isHost(host types.Session) bool {
|
func (manager *SessionManagerCtx) isHost(host types.Session) bool {
|
||||||
hostId, ok := manager.hostId.Load().(string)
|
hostId, ok := manager.hostId.Load().(string)
|
||||||
return ok && hostId == host.ID()
|
return ok && hostId == host.ID()
|
||||||
@ -357,12 +353,12 @@ func (manager *SessionManagerCtx) OnStateChanged(listener func(session types.Ses
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *SessionManagerCtx) OnHostChanged(listener func(session types.Session)) {
|
func (manager *SessionManagerCtx) OnHostChanged(listener func(session, host types.Session)) {
|
||||||
manager.emmiter.On("host_changed", func(payload ...any) {
|
manager.emmiter.On("host_changed", func(payload ...any) {
|
||||||
if payload[0] == nil {
|
if payload[1] == nil {
|
||||||
listener(nil)
|
listener(payload[0].(*SessionCtx), nil)
|
||||||
} else {
|
} else {
|
||||||
listener(payload[0].(*SessionCtx))
|
listener(payload[0].(*SessionCtx), payload[1].(*SessionCtx))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -394,16 +390,16 @@ func (manager *SessionManagerCtx) updateSettings(session types.Session, new, old
|
|||||||
// if private mode changed
|
// if private mode changed
|
||||||
if old.PrivateMode != new.PrivateMode {
|
if old.PrivateMode != new.PrivateMode {
|
||||||
// update webrtc paused state for all sessions
|
// update webrtc paused state for all sessions
|
||||||
for _, session := range manager.List() {
|
for _, s := range manager.List() {
|
||||||
enabled := session.PrivateModeEnabled()
|
enabled := s.PrivateModeEnabled()
|
||||||
|
|
||||||
// if session had control, it must release it
|
// if session had control, it must release it
|
||||||
if enabled && session.IsHost() {
|
if enabled && s.IsHost() {
|
||||||
manager.ClearHost()
|
session.ClearHost()
|
||||||
}
|
}
|
||||||
|
|
||||||
// its webrtc connection will be paused or unpaused
|
// its webrtc connection will be paused or unpaused
|
||||||
if webrtcPeer := session.GetWebRTCPeer(); webrtcPeer != nil {
|
if webrtcPeer := s.GetWebRTCPeer(); webrtcPeer != nil {
|
||||||
webrtcPeer.SetPaused(enabled)
|
webrtcPeer.SetPaused(enabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,7 +430,7 @@ func (manager *SessionManagerCtx) updateSettings(session types.Session, new, old
|
|||||||
// if the host is not admin, it must release controls
|
// if the host is not admin, it must release controls
|
||||||
host, hasHost := manager.GetHost()
|
host, hasHost := manager.GetHost()
|
||||||
if hasHost && !host.Profile().IsAdmin {
|
if hasHost && !host.Profile().IsAdmin {
|
||||||
manager.ClearHost()
|
session.ClearHost()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ func (session *SessionCtx) Profile() types.MemberProfile {
|
|||||||
|
|
||||||
func (session *SessionCtx) profileChanged() {
|
func (session *SessionCtx) profileChanged() {
|
||||||
if !session.profile.CanHost && session.IsHost() {
|
if !session.profile.CanHost && session.IsHost() {
|
||||||
session.manager.ClearHost()
|
session.ClearHost()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!session.profile.CanConnect || !session.profile.CanLogin || !session.profile.CanWatch) && session.state.IsWatching {
|
if (!session.profile.CanConnect || !session.profile.CanLogin || !session.profile.CanWatch) && session.state.IsWatching {
|
||||||
@ -68,6 +68,18 @@ func (session *SessionCtx) IsHost() bool {
|
|||||||
return session.manager.isHost(session)
|
return session.manager.isHost(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (session *SessionCtx) SetAsHost() {
|
||||||
|
session.manager.setHost(session, session)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (session *SessionCtx) SetAsHostBy(host types.Session) {
|
||||||
|
session.manager.setHost(session, host)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (session *SessionCtx) ClearHost() {
|
||||||
|
session.manager.setHost(session, nil)
|
||||||
|
}
|
||||||
|
|
||||||
func (session *SessionCtx) PrivateModeEnabled() bool {
|
func (session *SessionCtx) PrivateModeEnabled() bool {
|
||||||
return session.manager.Settings().PrivateMode && !session.profile.IsAdmin
|
return session.manager.Settings().PrivateMode && !session.profile.IsAdmin
|
||||||
}
|
}
|
||||||
@ -82,10 +94,8 @@ func (session *SessionCtx) SetCursor(cursor types.Cursor) {
|
|||||||
// websocket
|
// websocket
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
//
|
|
||||||
// Connect WebSocket peer sets current peer and emits connected event. It also destroys the
|
// Connect WebSocket peer sets current peer and emits connected event. It also destroys the
|
||||||
// previous peer, if there was one. If the peer is already set, it will be ignored.
|
// previous peer, if there was one. If the peer is already set, it will be ignored.
|
||||||
//
|
|
||||||
func (session *SessionCtx) ConnectWebSocketPeer(websocketPeer types.WebSocketPeer) {
|
func (session *SessionCtx) ConnectWebSocketPeer(websocketPeer types.WebSocketPeer) {
|
||||||
session.websocketMu.Lock()
|
session.websocketMu.Lock()
|
||||||
isCurrentPeer := websocketPeer == session.websocketPeer
|
isCurrentPeer := websocketPeer == session.websocketPeer
|
||||||
@ -113,14 +123,12 @@ func (session *SessionCtx) ConnectWebSocketPeer(websocketPeer types.WebSocketPee
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Disconnect WebSocket peer sets current peer to nil and emits disconnected event. It also
|
// Disconnect WebSocket peer sets current peer to nil and emits disconnected event. It also
|
||||||
// allows for a delayed disconnect. That means, the peer will not be disconnected immediately,
|
// allows for a delayed disconnect. That means, the peer will not be disconnected immediately,
|
||||||
// but after a delay. If the peer is connected again before the delay, the disconnect will be
|
// but after a delay. If the peer is connected again before the delay, the disconnect will be
|
||||||
// cancelled.
|
// cancelled.
|
||||||
//
|
//
|
||||||
// If the peer is not the current peer or the peer is nil, it will be ignored.
|
// If the peer is not the current peer or the peer is nil, it will be ignored.
|
||||||
//
|
|
||||||
func (session *SessionCtx) DisconnectWebSocketPeer(websocketPeer types.WebSocketPeer, delayed bool) {
|
func (session *SessionCtx) DisconnectWebSocketPeer(websocketPeer types.WebSocketPeer, delayed bool) {
|
||||||
session.websocketMu.Lock()
|
session.websocketMu.Lock()
|
||||||
isCurrentPeer := websocketPeer == session.websocketPeer && websocketPeer != nil
|
isCurrentPeer := websocketPeer == session.websocketPeer && websocketPeer != nil
|
||||||
@ -175,10 +183,8 @@ func (session *SessionCtx) DisconnectWebSocketPeer(websocketPeer types.WebSocket
|
|||||||
session.websocketMu.Unlock()
|
session.websocketMu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Destroy WebSocket peer disconnects the peer and destroys it. It ensures that the peer is
|
// Destroy WebSocket peer disconnects the peer and destroys it. It ensures that the peer is
|
||||||
// disconnected immediately even though normal flow would be to disconnect it delayed.
|
// disconnected immediately even though normal flow would be to disconnect it delayed.
|
||||||
//
|
|
||||||
func (session *SessionCtx) DestroyWebSocketPeer(reason string) {
|
func (session *SessionCtx) DestroyWebSocketPeer(reason string) {
|
||||||
session.websocketMu.Lock()
|
session.websocketMu.Lock()
|
||||||
peer := session.websocketPeer
|
peer := session.websocketPeer
|
||||||
@ -195,9 +201,7 @@ func (session *SessionCtx) DestroyWebSocketPeer(reason string) {
|
|||||||
peer.Destroy(reason)
|
peer.Destroy(reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Send event to websocket peer.
|
// Send event to websocket peer.
|
||||||
//
|
|
||||||
func (session *SessionCtx) Send(event string, payload any) {
|
func (session *SessionCtx) Send(event string, payload any) {
|
||||||
session.websocketMu.Lock()
|
session.websocketMu.Lock()
|
||||||
peer := session.websocketPeer
|
peer := session.websocketPeer
|
||||||
@ -212,9 +216,7 @@ func (session *SessionCtx) Send(event string, payload any) {
|
|||||||
// webrtc
|
// webrtc
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
//
|
|
||||||
// Set webrtc peer and destroy the old one, if there is old one.
|
// Set webrtc peer and destroy the old one, if there is old one.
|
||||||
//
|
|
||||||
func (session *SessionCtx) SetWebRTCPeer(webrtcPeer types.WebRTCPeer) {
|
func (session *SessionCtx) SetWebRTCPeer(webrtcPeer types.WebRTCPeer) {
|
||||||
session.webrtcMu.Lock()
|
session.webrtcMu.Lock()
|
||||||
session.webrtcPeer, webrtcPeer = webrtcPeer, session.webrtcPeer
|
session.webrtcPeer, webrtcPeer = webrtcPeer, session.webrtcPeer
|
||||||
@ -225,14 +227,12 @@ func (session *SessionCtx) SetWebRTCPeer(webrtcPeer types.WebRTCPeer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Set if current webrtc peer is connected or not. Since there might be lefover calls from
|
// Set if current webrtc peer is connected or not. Since there might be lefover calls from
|
||||||
// webrtc peer, that are not used anymore, we need to check if the webrtc peer is still the
|
// webrtc peer, that are not used anymore, we need to check if the webrtc peer is still the
|
||||||
// same as the one we are setting the connected state for.
|
// same as the one we are setting the connected state for.
|
||||||
//
|
//
|
||||||
// If webrtc peer is disconnected, we don't expect it to be reconnected, so we set it to nil
|
// If webrtc peer is disconnected, we don't expect it to be reconnected, so we set it to nil
|
||||||
// and send a signal close to the client. New connection is expected to use a new webrtc peer.
|
// and send a signal close to the client. New connection is expected to use a new webrtc peer.
|
||||||
//
|
|
||||||
func (session *SessionCtx) SetWebRTCConnected(webrtcPeer types.WebRTCPeer, connected bool) {
|
func (session *SessionCtx) SetWebRTCConnected(webrtcPeer types.WebRTCPeer, connected bool) {
|
||||||
session.webrtcMu.Lock()
|
session.webrtcMu.Lock()
|
||||||
isCurrentPeer := webrtcPeer == session.webrtcPeer
|
isCurrentPeer := webrtcPeer == session.webrtcPeer
|
||||||
@ -274,9 +274,7 @@ func (session *SessionCtx) SetWebRTCConnected(webrtcPeer types.WebRTCPeer, conne
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Get current WebRTC peer. Nil if not connected.
|
// Get current WebRTC peer. Nil if not connected.
|
||||||
//
|
|
||||||
func (session *SessionCtx) GetWebRTCPeer() types.WebRTCPeer {
|
func (session *SessionCtx) GetWebRTCPeer() types.WebRTCPeer {
|
||||||
session.webrtcMu.Lock()
|
session.webrtcMu.Lock()
|
||||||
defer session.webrtcMu.Unlock()
|
defer session.webrtcMu.Unlock()
|
||||||
|
@ -26,7 +26,7 @@ func (h *MessageHandlerCtx) controlRelease(session types.Session) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h.desktop.ResetKeys()
|
h.desktop.ResetKeys()
|
||||||
h.sessions.ClearHost()
|
session.ClearHost()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ func (h *MessageHandlerCtx) controlRequest(session types.Session) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h.sessions.SetHost(session)
|
session.SetAsHost()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ func (h *MessageHandlerCtx) SessionDisconnected(session types.Session) error {
|
|||||||
// clear host if exists
|
// clear host if exists
|
||||||
if session.IsHost() {
|
if session.IsHost() {
|
||||||
h.desktop.ResetKeys()
|
h.desktop.ResetKeys()
|
||||||
h.sessions.ClearHost()
|
session.ClearHost()
|
||||||
}
|
}
|
||||||
|
|
||||||
if session.Profile().IsAdmin {
|
if session.Profile().IsAdmin {
|
||||||
|
@ -110,18 +110,20 @@ func (manager *WebSocketManagerCtx) Start() {
|
|||||||
Msg("session state changed")
|
Msg("session state changed")
|
||||||
})
|
})
|
||||||
|
|
||||||
manager.sessions.OnHostChanged(func(session types.Session) {
|
manager.sessions.OnHostChanged(func(session, host types.Session) {
|
||||||
payload := message.ControlHost{
|
payload := message.ControlHost{
|
||||||
HasHost: session != nil,
|
ID: session.ID(),
|
||||||
|
HasHost: host != nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
if payload.HasHost {
|
if payload.HasHost {
|
||||||
payload.HostID = session.ID()
|
payload.HostID = host.ID()
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.sessions.Broadcast(event.CONTROL_HOST, payload)
|
manager.sessions.Broadcast(event.CONTROL_HOST, payload)
|
||||||
|
|
||||||
manager.logger.Info().
|
manager.logger.Info().
|
||||||
|
Str("session_id", session.ID()).
|
||||||
Bool("has_host", payload.HasHost).
|
Bool("has_host", payload.HasHost).
|
||||||
Str("host_id", payload.HostID).
|
Str("host_id", payload.HostID).
|
||||||
Msg("session host changed")
|
Msg("session host changed")
|
||||||
|
@ -97,7 +97,7 @@ func TestHostsOnly(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// r2 is host
|
// r2 is host
|
||||||
sessionManager.SetHost(session)
|
session.SetAsHost()
|
||||||
|
|
||||||
r3, _, err := rWithSession(types.MemberProfile{CanHost: false})
|
r3, _, err := rWithSession(types.MemberProfile{CanHost: false})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -116,6 +116,7 @@ type SessionCursors struct {
|
|||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
|
|
||||||
type ControlHost struct {
|
type ControlHost struct {
|
||||||
|
ID string `json:"id"`
|
||||||
HasHost bool `json:"has_host"`
|
HasHost bool `json:"has_host"`
|
||||||
HostID string `json:"host_id,omitempty"`
|
HostID string `json:"host_id,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,9 @@ type Session interface {
|
|||||||
Profile() MemberProfile
|
Profile() MemberProfile
|
||||||
State() SessionState
|
State() SessionState
|
||||||
IsHost() bool
|
IsHost() bool
|
||||||
|
SetAsHost()
|
||||||
|
SetAsHostBy(session Session)
|
||||||
|
ClearHost()
|
||||||
PrivateModeEnabled() bool
|
PrivateModeEnabled() bool
|
||||||
|
|
||||||
// cursor
|
// cursor
|
||||||
@ -83,9 +86,7 @@ type SessionManager interface {
|
|||||||
List() []Session
|
List() []Session
|
||||||
Range(func(Session) bool)
|
Range(func(Session) bool)
|
||||||
|
|
||||||
SetHost(host Session)
|
|
||||||
GetHost() (Session, bool)
|
GetHost() (Session, bool)
|
||||||
ClearHost()
|
|
||||||
|
|
||||||
SetCursor(cursor Cursor, session Session)
|
SetCursor(cursor Cursor, session Session)
|
||||||
PopCursors() map[Session][]Cursor
|
PopCursors() map[Session][]Cursor
|
||||||
@ -100,7 +101,7 @@ type SessionManager interface {
|
|||||||
OnDisconnected(listener func(session Session))
|
OnDisconnected(listener func(session Session))
|
||||||
OnProfileChanged(listener func(session Session))
|
OnProfileChanged(listener func(session Session))
|
||||||
OnStateChanged(listener func(session Session))
|
OnStateChanged(listener func(session Session))
|
||||||
OnHostChanged(listener func(session Session))
|
OnHostChanged(listener func(session, host Session))
|
||||||
OnSettingsChanged(listener func(session Session, new Settings, old Settings))
|
OnSettingsChanged(listener func(session Session, new Settings, old Settings))
|
||||||
|
|
||||||
UpdateSettingsFunc(session Session, f func(settings *Settings) bool)
|
UpdateSettingsFunc(session Session, f func(settings *Settings) bool)
|
||||||
|
Loading…
Reference in New Issue
Block a user