buffet: Add periodic pings to XMPP connection
In order to monitor XMPP connection, we are implementing support
for XMPP pings described in XEP-0199 extension to XMPP standard
(see: http://xmpp.org/extensions/xep-0199.html#c2s).
Now we send ping requests to XMPP server every 60 seconds and if
we receive no response, we assume the connection is broken and
initiate immediate re-connection.
BUG=brillo:1138
TEST=`FEATURES=test emerge-link buffet`
Change-Id: Id2c092a0454b360d2c18bef5e30e3461ceeddab8
Reviewed-on: https://chromium-review.googlesource.com/274060
Reviewed-by: Vitaly Buka <vitalybuka@chromium.org>
Trybot-Ready: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/notification/xmpp_channel.cc b/buffet/notification/xmpp_channel.cc
index ab657d1..9bf9463 100644
--- a/buffet/notification/xmpp_channel.cc
+++ b/buffet/notification/xmpp_channel.cc
@@ -75,6 +75,7 @@
const char kDefaultXmppHost[] = "talk.google.com";
const uint16_t kDefaultXmppPort = 5222;
+const uint64_t kPingIntervalSeconds = 60; // 1 minute.
} // namespace
@@ -88,6 +89,7 @@
task_runner_{task_runner},
iq_stanza_handler_{new IqStanzaHandler{this, task_runner}} {
read_socket_data_.resize(4096);
+ ping_timer_.SetTaskRunner(task_runner);
}
void XmppChannel::OnMessageRead(size_t size) {
@@ -417,6 +419,8 @@
delegate_->OnDisconnected();
weak_ptr_factory_.InvalidateWeakPtrs();
+ StopPingTimer();
+
if (tls_stream_) {
tls_stream_->CloseBlocking(nullptr);
tls_stream_.reset();
@@ -432,6 +436,7 @@
void XmppChannel::OnConnected() {
state_ = XmppState::kStarted;
RestartXmppStream();
+ StartPingTimer();
}
void XmppChannel::RestartXmppStream() {
@@ -442,4 +447,34 @@
SendMessage(BuildXmppStartStreamCommand());
}
+void XmppChannel::StartPingTimer() {
+ ping_timer_.Start(FROM_HERE,
+ base::TimeDelta::FromSeconds(kPingIntervalSeconds),
+ base::Bind(&XmppChannel::PingServer,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void XmppChannel::StopPingTimer() {
+ ping_timer_.Stop();
+}
+
+void XmppChannel::PingServer() {
+ // Send an XMPP Ping request as defined in XEP-0199 extension:
+ // http://xmpp.org/extensions/xep-0199.html
+ iq_stanza_handler_->SendRequest(
+ "get", jid_, account_, "<ping xmlns='urn:xmpp:ping'/>",
+ base::Bind(&XmppChannel::OnPingResponse, weak_ptr_factory_.GetWeakPtr()),
+ base::Bind(&XmppChannel::OnPingTimeout, weak_ptr_factory_.GetWeakPtr()));
+}
+
+void XmppChannel::OnPingResponse(std::unique_ptr<XmlNode> reply) {
+ // Ping response received from server. Everything seems to be in order.
+ // Nothing else to do.
+}
+
+void XmppChannel::OnPingTimeout() {
+ LOG(WARNING) << "XMPP channel seems to be disconnected - ping timed out";
+ Restart();
+}
+
} // namespace buffet