add merciful reconnect option.

This commit is contained in:
Miroslav Šedivý 2021-08-23 18:41:19 +02:00
parent 01c0f269ee
commit b2ae808233
4 changed files with 35 additions and 14 deletions

View File

@ -8,8 +8,9 @@ import (
) )
type Session struct { type Session struct {
ImplicitHosting bool ImplicitHosting bool
APIToken string MercifulReconnect bool
APIToken string
CookieEnabled bool CookieEnabled bool
CookieName string CookieName string
@ -23,6 +24,11 @@ func (Session) Init(cmd *cobra.Command) error {
return err return err
} }
cmd.PersistentFlags().Bool("session.merciful_reconnect", true, "allow reconnecting to websocket even if previous connection was not closed")
if err := viper.BindPFlag("session.merciful_reconnect", cmd.PersistentFlags().Lookup("session.merciful_reconnect")); err != nil {
return err
}
cmd.PersistentFlags().String("session.api_token", "", "API token for interacting with external services") cmd.PersistentFlags().String("session.api_token", "", "API token for interacting with external services")
if err := viper.BindPFlag("session.api_token", cmd.PersistentFlags().Lookup("session.api_token")); err != nil { if err := viper.BindPFlag("session.api_token", cmd.PersistentFlags().Lookup("session.api_token")); err != nil {
return err return err
@ -54,6 +60,7 @@ func (Session) Init(cmd *cobra.Command) error {
func (s *Session) Set() { func (s *Session) Set() {
s.ImplicitHosting = viper.GetBool("session.implicit_hosting") s.ImplicitHosting = viper.GetBool("session.implicit_hosting")
s.MercifulReconnect = viper.GetBool("session.merciful_reconnect")
s.APIToken = viper.GetString("session.api_token") s.APIToken = viper.GetString("session.api_token")
s.CookieEnabled = viper.GetBool("session.cookie.enabled") s.CookieEnabled = viper.GetBool("session.cookie.enabled")

View File

@ -304,3 +304,7 @@ func (manager *SessionManagerCtx) ImplicitHosting() bool {
func (manager *SessionManagerCtx) CookieEnabled() bool { func (manager *SessionManagerCtx) CookieEnabled() bool {
return manager.config.CookieEnabled return manager.config.CookieEnabled
} }
func (manager *SessionManagerCtx) MercifulReconnect() bool {
return manager.config.MercifulReconnect
}

View File

@ -50,6 +50,7 @@ type SessionManager interface {
ImplicitHosting() bool ImplicitHosting() bool
CookieEnabled() bool CookieEnabled() bool
MercifulReconnect() bool
CookieSetToken(w http.ResponseWriter, token string) CookieSetToken(w http.ResponseWriter, token string)
CookieClearToken(w http.ResponseWriter, r *http.Request) CookieClearToken(w http.ResponseWriter, r *http.Request)

View File

@ -189,22 +189,31 @@ func (manager *WebSocketManagerCtx) Upgrade(w http.ResponseWriter, r *http.Reque
} }
if session.State().IsConnected { if session.State().IsConnected {
manager.logger.Debug().Str("session_id", session.ID()).Msg("already connected") manager.logger.Warn().Str("session_id", session.ID()).Msg("already connected")
// TODO: Refactor, return error code. if !manager.sessions.MercifulReconnect() {
if err = connection.WriteJSON( // TODO: Refactor, return error code.
message.SystemDisconnect{ if err = connection.WriteJSON(
Event: event.SYSTEM_DISCONNECT, message.SystemDisconnect{
Message: "already connected", Event: event.SYSTEM_DISCONNECT,
}); err != nil { Message: "already connected",
manager.logger.Error().Err(err).Msg("failed to send disconnect event") }); err != nil {
manager.logger.Error().Err(err).Msg("failed to send disconnect event")
}
if err := connection.Close(); err != nil {
manager.logger.Warn().Err(err).Msg("connection closed with an error")
}
return
} }
if err := connection.Close(); err != nil { manager.logger.Debug().Str("session_id", session.ID()).Msg("replacing peer connection")
manager.logger.Warn().Err(err).Msg("connection closed with an error")
}
return // replace peer connection
if err := session.GetWebSocketPeer().Destroy(); err != nil {
manager.logger.Warn().Err(err).Msg("previous connection closed with an error")
}
} }
peer := &WebSocketPeerCtx{ peer := &WebSocketPeerCtx{