Temporary websocket disconnect handling (#6)

* fix websocket close log error.

* logger session interface no pointer.

* websocket delayet disconnect.

* session host: save id not pointer to a session.

* fix if hostId not stored.
This commit is contained in:
Miroslav Šedivý
2022-08-26 20:16:40 +02:00
committed by GitHub
parent 5612b80634
commit 691150900b
9 changed files with 122 additions and 61 deletions

View File

@ -3,6 +3,7 @@ package session
import (
"errors"
"sync"
"sync/atomic"
"github.com/kataras/go-events"
"github.com/rs/zerolog"
@ -62,8 +63,7 @@ type SessionManagerCtx struct {
sessions map[string]*SessionCtx
sessionsMu sync.Mutex
host types.Session
hostMu sync.Mutex
hostId atomic.Value
cursors map[types.Session][]types.Cursor
cursorsMu sync.Mutex
@ -188,24 +188,33 @@ func (manager *SessionManagerCtx) List() []types.Session {
// ---
func (manager *SessionManagerCtx) SetHost(host types.Session) {
manager.hostMu.Lock()
manager.host = host
manager.hostMu.Unlock()
var hostId string
if host != nil {
hostId = host.ID()
}
manager.hostId.Store(hostId)
manager.emmiter.Emit("host_changed", host)
}
func (manager *SessionManagerCtx) GetHost() types.Session {
manager.hostMu.Lock()
defer manager.hostMu.Unlock()
func (manager *SessionManagerCtx) GetHost() (types.Session, bool) {
hostId, ok := manager.hostId.Load().(string)
if !ok || hostId == "" {
return nil, false
}
return manager.host
return manager.Get(hostId)
}
func (manager *SessionManagerCtx) ClearHost() {
manager.SetHost(nil)
}
func (manager *SessionManagerCtx) isHost(host types.Session) bool {
hostId, ok := manager.hostId.Load().(string)
return ok && hostId == host.ID()
}
// ---
// cursors
// ---

View File

@ -2,6 +2,7 @@ package session
import (
"sync"
"time"
"github.com/rs/zerolog"
@ -9,6 +10,10 @@ import (
"github.com/demodesk/neko/pkg/types/event"
)
// client is expected to reconnect within 5 second
// if some unexpected websocket disconnect happens
const WS_DELAYED_DURATION = 5 * time.Second
type SessionCtx struct {
id string
token string
@ -20,6 +25,10 @@ type SessionCtx struct {
websocketPeer types.WebSocketPeer
websocketMu sync.Mutex
// websocket delayed set connected events
wsDelayedMu sync.Mutex
wsDelayedTimer *time.Timer
webrtcPeer types.WebRTCPeer
webrtcMu sync.Mutex
}
@ -56,7 +65,7 @@ func (session *SessionCtx) State() types.SessionState {
}
func (session *SessionCtx) IsHost() bool {
return session.manager.GetHost() == session
return session.manager.isHost(session)
}
func (session *SessionCtx) PrivateModeEnabled() bool {
@ -83,7 +92,7 @@ func (session *SessionCtx) SetWebSocketPeer(websocketPeer types.WebSocketPeer) {
}
}
func (session *SessionCtx) SetWebSocketConnected(websocketPeer types.WebSocketPeer, connected bool) {
func (session *SessionCtx) SetWebSocketConnected(websocketPeer types.WebSocketPeer, connected bool, delayed bool) {
session.websocketMu.Lock()
isCurrentPeer := websocketPeer == session.websocketPeer
session.websocketMu.Unlock()
@ -94,8 +103,36 @@ func (session *SessionCtx) SetWebSocketConnected(websocketPeer types.WebSocketPe
session.logger.Info().
Bool("connected", connected).
Bool("delayed", delayed).
Msg("set websocket connected")
//
// ws delayed
//
var wsDelayedTimer *time.Timer
if delayed {
wsDelayedTimer = time.AfterFunc(WS_DELAYED_DURATION, func() {
session.SetWebSocketConnected(websocketPeer, connected, false)
})
}
session.wsDelayedMu.Lock()
if session.wsDelayedTimer != nil {
session.wsDelayedTimer.Stop()
}
session.wsDelayedTimer = wsDelayedTimer
session.wsDelayedMu.Unlock()
if delayed {
return
}
//
// not delayed
//
session.state.IsConnected = connected
if connected {