Small connection fixes

This commit is contained in:
fiaxh 2018-03-10 19:46:08 +01:00
parent c6ff25cc7a
commit 4ccdc1d092
4 changed files with 43 additions and 43 deletions

View file

@ -41,7 +41,7 @@ public interface Dino.Application : GLib.Application {
create_actions(); create_actions();
activate.connect(() => { startup.connect(() => {
stream_interactor.connection_manager.log_options = print_xmpp; stream_interactor.connection_manager.log_options = print_xmpp;
Idle.add(() => { Idle.add(() => {
restore(); restore();

View file

@ -17,7 +17,7 @@ public class ConnectionManager {
DISCONNECTED DISCONNECTED
} }
private ArrayList<Account> connection_todo = new ArrayList<Account>(Account.equals_func); private HashSet<Account> connection_todo = new HashSet<Account>(Account.hash_func, Account.equals_func);
private HashMap<Account, Connection> connections = new HashMap<Account, Connection>(Account.hash_func, Account.equals_func); private HashMap<Account, Connection> connections = new HashMap<Account, Connection>(Account.hash_func, Account.equals_func);
private HashMap<Account, ConnectionError> connection_errors = new HashMap<Account, ConnectionError>(Account.hash_func, Account.equals_func); private HashMap<Account, ConnectionError> connection_errors = new HashMap<Account, ConnectionError>(Account.hash_func, Account.equals_func);
@ -106,7 +106,7 @@ public class ConnectionManager {
return null; return null;
} }
public ArrayList<Account> get_managed_accounts() { public Collection<Account> get_managed_accounts() {
return connection_todo; return connection_todo;
} }
@ -154,6 +154,7 @@ public class ConnectionManager {
stream.add_module(module); stream.add_module(module);
} }
stream.log = new XmppLog(account.bare_jid.to_string(), log_options); stream.log = new XmppLog(account.bare_jid.to_string(), log_options);
print("[%s] New connection with resource %s: %p\n".printf(account.bare_jid.to_string(), resource, stream));
Connection connection = new Connection(stream, new DateTime.now_utc()); Connection connection = new Connection(stream, new DateTime.now_utc());
connections[account] = connection; connections[account] = connection;
@ -178,10 +179,9 @@ public class ConnectionManager {
try { try {
yield stream.connect(account.domainpart); yield stream.connect(account.domainpart);
} catch (Error e) { } catch (Error e) {
stderr.printf("Stream Error: %s\n", e.message); print(@"[$(account.bare_jid)] Error: $(e.message)\n");
change_connection_state(account, ConnectionState.DISCONNECTED); change_connection_state(account, ConnectionState.DISCONNECTED);
if (!connection_todo.contains(account)) { if (!connection_todo.contains(account)) {
connections.unset(account);
return; return;
} }
if (e is IOStreamError.TLS) { if (e is IOStreamError.TLS) {
@ -192,16 +192,13 @@ public class ConnectionManager {
if (flag != null) { if (flag != null) {
set_connection_error(account, new ConnectionError(ConnectionError.Source.STREAM_ERROR, flag.error_type) { resource_rejected=flag.resource_rejected }); set_connection_error(account, new ConnectionError(ConnectionError.Source.STREAM_ERROR, flag.error_type) { resource_rejected=flag.resource_rejected });
} }
interpret_connection_error(account);
}
}
private void interpret_connection_error(Account account) {
ConnectionError? error = connection_errors[account]; ConnectionError? error = connection_errors[account];
int wait_sec = 5; int wait_sec = 5;
if (error == null) { if (error == null) {
wait_sec = 3; wait_sec = 3;
} else if (error.source == ConnectionError.Source.STREAM_ERROR) { } else if (error.source == ConnectionError.Source.STREAM_ERROR) {
print(@"[$(account.bare_jid)] Stream Error: $(error.identifier)\n");
if (error.resource_rejected) { if (error.resource_rejected) {
connect_(account, account.resourcepart + "-" + random_uuid()); connect_(account, account.resourcepart + "-" + random_uuid());
return; return;
@ -217,15 +214,13 @@ public class ConnectionManager {
} else if (error.source == ConnectionError.Source.SASL) { } else if (error.source == ConnectionError.Source.SASL) {
return; return;
} }
if (network_is_online()) { print(@"[$(account.bare_jid)] Check reconnect in $wait_sec sec\n");
wait_sec = 30;
}
print(@"recovering in $wait_sec\n");
Timeout.add_seconds(wait_sec, () => { Timeout.add_seconds(wait_sec, () => {
check_reconnect(account); check_reconnect(account);
return false; return false;
}); });
} }
}
private void check_reconnects() { private void check_reconnects() {
foreach (Account account in connection_todo) { foreach (Account account in connection_todo) {
@ -237,7 +232,8 @@ public class ConnectionManager {
bool acked = false; bool acked = false;
XmppStream stream = connections[account].stream; XmppStream stream = connections[account].stream;
stream.get_module(Xep.Ping.Module.IDENTITY).send_ping(stream, account.bare_jid.domain_jid, (stream) => { stream.get_module(Xep.Ping.Module.IDENTITY).send_ping(stream, account.bare_jid.domain_jid, () => {
if (connections[account].stream != stream) return;
acked = true; acked = true;
change_connection_state(account, ConnectionState.CONNECTED); change_connection_state(account, ConnectionState.CONNECTED);
}); });
@ -267,10 +263,10 @@ public class ConnectionManager {
private void on_network_changed() { private void on_network_changed() {
if (network_is_online()) { if (network_is_online()) {
print("network online\n"); print("Network reported online\n");
check_reconnects(); check_reconnects();
} else { } else {
print("network offline\n"); print("Network reported offline\n");
foreach (Account account in connection_todo) { foreach (Account account in connection_todo) {
change_connection_state(account, ConnectionState.DISCONNECTED); change_connection_state(account, ConnectionState.DISCONNECTED);
} }
@ -282,17 +278,15 @@ public class ConnectionManager {
change_connection_state(account, ConnectionState.DISCONNECTED); change_connection_state(account, ConnectionState.DISCONNECTED);
} }
if (suspend) { if (suspend) {
print("suspend\n"); print("Device suspended\n");
foreach (Account account in connection_todo) { foreach (Account account in connection_todo) {
Xmpp.Presence.Stanza presence = new Xmpp.Presence.Stanza();
presence.type_ = Xmpp.Presence.Stanza.TYPE_UNAVAILABLE;
try { try {
connections[account].stream.get_module(Presence.Module.IDENTITY).send_presence(connections[account].stream, presence); make_offline(account);
connections[account].stream.disconnect(); connections[account].stream.disconnect();
} catch (Error e) { print(@"on_prepare_for_sleep error $(e.message)\n"); } } catch (Error e) { print(@"on_prepare_for_sleep error $(e.message)\n"); }
} }
} else { } else {
print("un-suspend\n"); print("Device un-suspend\n");
check_reconnects(); check_reconnects();
} }
} }

View file

@ -40,7 +40,7 @@ public class ModuleManager {
foreach (XmppStreamModule module in module_map[account]) { foreach (XmppStreamModule module in module_map[account]) {
if (module.get_id() == Bind.Module.IDENTITY.id) { if (module.get_id() == Bind.Module.IDENTITY.id) {
(module as Bind.Module).requested_resource == null ? account.resourcepart : resource; (module as Bind.Module).requested_resource = resource ?? account.resourcepart;
} else if (module.get_id() == PlainSasl.Module.IDENTITY.id) { } else if (module.get_id() == PlainSasl.Module.IDENTITY.id) {
(module as PlainSasl.Module).password = account.password; (module as PlainSasl.Module).password = account.password;
} }

View file

@ -151,6 +151,12 @@ public class XmppStream {
} }
public XmppStream add_module(XmppStreamModule module) { public XmppStream add_module(XmppStreamModule module) {
foreach (XmppStreamModule m in modules) {
if (m.get_ns() == module.get_ns() && m.get_id() == module.get_id()) {
print("[%p] Adding already added module: %s\n".printf(this, module.get_id()));
return this;
}
}
modules.add(module); modules.add(module);
if (negotiation_complete) module.attach(this); if (negotiation_complete) module.attach(this);
return this; return this;