Small connection fixes
This commit is contained in:
parent
c6ff25cc7a
commit
4ccdc1d092
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue