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 {
ImplicitHosting bool
APIToken string
ImplicitHosting bool
MercifulReconnect bool
APIToken string
CookieEnabled bool
CookieName string
@ -23,6 +24,11 @@ func (Session) Init(cmd *cobra.Command) error {
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")
if err := viper.BindPFlag("session.api_token", cmd.PersistentFlags().Lookup("session.api_token")); err != nil {
return err
@ -54,6 +60,7 @@ func (Session) Init(cmd *cobra.Command) error {
func (s *Session) Set() {
s.ImplicitHosting = viper.GetBool("session.implicit_hosting")
s.MercifulReconnect = viper.GetBool("session.merciful_reconnect")
s.APIToken = viper.GetString("session.api_token")
s.CookieEnabled = viper.GetBool("session.cookie.enabled")

View File

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

View File

@ -50,6 +50,7 @@ type SessionManager interface {
ImplicitHosting() bool
CookieEnabled() bool
MercifulReconnect() bool
CookieSetToken(w http.ResponseWriter, token string)
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 {
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 err = connection.WriteJSON(
message.SystemDisconnect{
Event: event.SYSTEM_DISCONNECT,
Message: "already connected",
}); err != nil {
manager.logger.Error().Err(err).Msg("failed to send disconnect event")
if !manager.sessions.MercifulReconnect() {
// TODO: Refactor, return error code.
if err = connection.WriteJSON(
message.SystemDisconnect{
Event: event.SYSTEM_DISCONNECT,
Message: "already connected",
}); 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.Warn().Err(err).Msg("connection closed with an error")
}
manager.logger.Debug().Str("session_id", session.ID()).Msg("replacing peer connection")
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{