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

@ -13,8 +13,8 @@ func (manager *WebSocketManagerCtx) fileChooserDialogEvents() {
manager.desktop.OnFileChooserDialogOpened(func() {
manager.logger.Info().Msg("file chooser dialog opened")
host := manager.sessions.GetHost()
if host == nil {
host, hasHost := manager.sessions.GetHost()
if !hasHost {
manager.logger.Warn().Msg("no host for file chooser dialog found, closing")
go manager.desktop.CloseFileChooserDialog()
return

View File

@ -42,7 +42,7 @@ func (h *MessageHandlerCtx) controlRequest(session types.Session) error {
if !h.sessions.Settings().ImplicitHosting {
// tell session if there is a host
if host := h.sessions.GetHost(); host != nil {
if host, hasHost := h.sessions.GetHost(); hasHost {
session.Send(
event.CONTROL_HOST,
message.ControlHost{

View File

@ -12,14 +12,16 @@ import (
)
func (h *MessageHandlerCtx) systemInit(session types.Session) error {
host := h.sessions.GetHost()
host, hasHost := h.sessions.GetHost()
controlHost := message.ControlHost{
HasHost: host != nil,
var hostID string
if hasHost {
hostID = host.ID()
}
if controlHost.HasHost {
controlHost.HostID = host.ID()
controlHost := message.ControlHost{
HasHost: hasHost,
HostID: hostID,
}
size := h.desktop.GetScreenSize()

View File

@ -132,8 +132,8 @@ func (manager *WebSocketManagerCtx) Start() {
})
manager.desktop.OnClipboardUpdated(func() {
session := manager.sessions.GetHost()
if session == nil || !session.Profile().CanAccessClipboard {
host, hasHost := manager.sessions.GetHost()
if !hasHost || !host.Profile().CanAccessClipboard {
return
}
@ -145,7 +145,7 @@ func (manager *WebSocketManagerCtx) Start() {
return
}
session.Send(
host.Send(
event.CLIPBOARD_UPDATED,
message.ClipboardData{
Text: data.Text,
@ -232,26 +232,47 @@ func (manager *WebSocketManagerCtx) connect(connection *websocket.Conn, r *http.
Str("agent", r.UserAgent()).
Msg("connection started")
session.SetWebSocketConnected(peer, true)
session.SetWebSocketConnected(peer, true, false)
defer func() {
logger.Info().
Str("address", connection.RemoteAddr().String()).
Str("agent", r.UserAgent()).
Msg("connection ended")
// this is a blocking function that lives
// throughout whole websocket connection
err = manager.handle(connection, peer, session)
session.SetWebSocketConnected(peer, false)
}()
logger.Info().
Str("address", connection.RemoteAddr().String()).
Str("agent", r.UserAgent()).
Msg("connection ended")
manager.handle(connection, peer, session)
delayedDisconnect := false
e, ok := err.(*websocket.CloseError)
if !ok {
logger.Err(err).Msg("read message error")
// client is expected to reconnect soon
delayedDisconnect = true
} else {
switch e.Code {
case websocket.CloseNormalClosure:
logger.Info().Str("reason", e.Text).Msg("websocket close")
case websocket.CloseGoingAway:
logger.Info().Str("reason", "going away").Msg("websocket close")
default:
logger.Warn().Err(err).Msg("websocket close")
// abnormal websocket closure:
// client is expected to reconnect soon
delayedDisconnect = true
}
}
session.SetWebSocketConnected(peer, false, delayedDisconnect)
}
func (manager *WebSocketManagerCtx) handle(connection *websocket.Conn, peer types.WebSocketPeer, session types.Session) {
func (manager *WebSocketManagerCtx) handle(connection *websocket.Conn, peer types.WebSocketPeer, session types.Session) error {
// add session id to logger context
logger := manager.logger.With().Str("session_id", session.ID()).Logger()
bytes := make(chan []byte)
cancel := make(chan struct{})
cancel := make(chan error)
ticker := time.NewTicker(pingPeriod)
defer ticker.Stop()
@ -263,13 +284,7 @@ func (manager *WebSocketManagerCtx) handle(connection *websocket.Conn, peer type
for {
_, raw, err := connection.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
logger.Warn().Err(err).Msg("read message error")
} else {
logger.Debug().Err(err).Msg("read message error")
}
close(cancel)
cancel <- err
break
}
@ -306,15 +321,14 @@ func (manager *WebSocketManagerCtx) handle(connection *websocket.Conn, peer type
if !handled {
logger.Warn().Str("event", data.Event).Msg("unhandled message")
}
case <-cancel:
return
case err := <-cancel:
return err
case <-manager.shutdown:
peer.Destroy("connection shutdown")
return
return nil
case <-ticker.C:
if err := peer.Ping(); err != nil {
logger.Err(err).Msg("ping message has failed")
return
return err
}
}
}