From fd1fd560bc7dedd33a4e5232dfbcd9e0f7d88c92 Mon Sep 17 00:00:00 2001 From: bodqhrohro Date: Fri, 10 Jan 2020 15:02:25 +0200 Subject: [PATCH] Try to resume connection and resend a stanza on failure --- xmpp/component.go | 4 ++-- xmpp/gateway/gateway.go | 28 +++++++++++++++++++++++----- xmpp/handlers.go | 16 ++++++++++++++-- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/xmpp/component.go b/xmpp/component.go index d1c71ae..bbf0483 100644 --- a/xmpp/component.go +++ b/xmpp/component.go @@ -76,9 +76,9 @@ func heartbeat(component *xmpp.Component) { for { time.Sleep(60e9) for key, presence := range gateway.Queue { - err = component.Send(presence) + err = gateway.ResumableSend(component, presence) if err != nil { - gateway.LogBadPresence(err, presence) + gateway.LogBadPresence(presence) } else { delete(gateway.Queue, key) } diff --git a/xmpp/gateway/gateway.go b/xmpp/gateway/gateway.go index 8629698..01269d0 100644 --- a/xmpp/gateway/gateway.go +++ b/xmpp/gateway/gateway.go @@ -2,6 +2,7 @@ package gateway import ( "encoding/xml" + "strings" "dev.narayana.im/narayana/telegabber/xmpp/extensions" @@ -55,12 +56,12 @@ func SendMessage(to string, from string, body string, component *xmpp.Component) } } - _ = component.Send(message) + _ = ResumableSend(component, message) } // LogBadPresence verbosely logs a presence -func LogBadPresence(err error, presence *stanza.Presence) { - log.Errorf("Couldn't send presence: %v: %#v", err, presence) +func LogBadPresence(presence *stanza.Presence) { + log.Errorf("Couldn't send presence: %#v", presence) } // SPFrom is a Telegram user id @@ -167,9 +168,9 @@ func SendPresence(component *xmpp.Component, to string, args ...args.V) error { immed := SPImmed.Get(args) if immed { - err := component.Send(presence) + err := ResumableSend(component, presence) if err != nil { - LogBadPresence(err, &presence) + LogBadPresence(&presence) return err } } else { @@ -178,3 +179,20 @@ func SendPresence(component *xmpp.Component, to string, args ...args.V) error { return nil } + +// ResumableSend tries to resume the connection once and sends the packet again +func ResumableSend(component *xmpp.Component, packet stanza.Packet) error { + err := component.Send(packet) + if err != nil && strings.HasPrefix(err.Error(), "cannot send packet") { + log.Warn("Packet send failed, trying to resume the connection...") + err = component.Connect() + if err == nil { + err = component.Send(packet) + } + } + + if err != nil { + log.Error(err.Error()) + } + return err +} diff --git a/xmpp/handlers.go b/xmpp/handlers.go index 8778423..2e44411 100644 --- a/xmpp/handlers.go +++ b/xmpp/handlers.go @@ -126,7 +126,13 @@ func handleSubscription(s xmpp.Sender, p stanza.Presence) { Type: "subscribed", }} - _ = s.Send(reply) + component, ok := s.(*xmpp.Component) + if !ok { + log.Error("Not a component") + return + } + + _ = gateway.ResumableSend(component, reply) } func handlePresence(s xmpp.Sender, p stanza.Presence) { @@ -262,5 +268,11 @@ func handleGetVcardTempIq(s xmpp.Sender, iq stanza.IQ) { } log.Debugf("%#v", answer) - _ = s.Send(answer) + component, ok := s.(*xmpp.Component) + if !ok { + log.Error("Not a component") + return + } + + _ = gateway.ResumableSend(component, answer) }