Move HTTPClient to the /sync API
The /events API is deprecated according to the Spec.
This commit is contained in:
parent
828c1448a9
commit
50e8d7cd92
@ -23,6 +23,7 @@
|
||||
public class Matrix.HTTPClient : Matrix.HTTPAPI, Matrix.Client {
|
||||
private bool _polling = false;
|
||||
private ulong _event_timeout = 30000;
|
||||
private string? _last_sync_token;
|
||||
|
||||
public
|
||||
HTTPClient(string base_url)
|
||||
@ -48,8 +49,8 @@ public class Matrix.HTTPClient : Matrix.HTTPAPI, Matrix.Client {
|
||||
|
||||
login((i, content_type, json_content, raw_content, error) => {
|
||||
login_finished((error == null) || (error is Matrix.Error.NONE));
|
||||
}
|
||||
,"m.login.password",
|
||||
},
|
||||
"m.login.password",
|
||||
builder.get_root());
|
||||
}
|
||||
|
||||
@ -75,84 +76,174 @@ public class Matrix.HTTPClient : Matrix.HTTPAPI, Matrix.Client {
|
||||
}
|
||||
|
||||
private void
|
||||
process_event(Json.Array ary, uint idx, Json.Node member_node)
|
||||
process_event(Json.Node event_node, string? room_id)
|
||||
{
|
||||
var root_obj = member_node.get_object();
|
||||
Json.Node? node;
|
||||
string? event_type = null;
|
||||
string? event_id = null;
|
||||
string? room_id = null;
|
||||
string? sender_id = null;
|
||||
UnsignedEventData? unsigned_data = null;
|
||||
Json.Object root_obj;
|
||||
Json.Node node;
|
||||
string event_type;
|
||||
Matrix.Event evt;
|
||||
|
||||
if ((node = root_obj.get_member("type")) != null) {
|
||||
event_type = node.get_string();
|
||||
if (event_node.get_node_type() != Json.NodeType.OBJECT) {
|
||||
warning("Received event that is not an object.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((node = root_obj.get_member("event_id")) != null) {
|
||||
event_id = node.get_string();
|
||||
root_obj = event_node.get_object();
|
||||
|
||||
if ((node = root_obj.get_member("type")) == null) {
|
||||
warning("Received event without type.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((node = root_obj.get_member("room_id")) != null) {
|
||||
room_id = node.get_string();
|
||||
}
|
||||
|
||||
if ((node = root_obj.get_member("sender")) != null) {
|
||||
sender_id = node.get_string();
|
||||
}
|
||||
|
||||
if ((node = root_obj.get_member("unsigned")) != null) {
|
||||
unsigned_data = new UnsignedEventData.from_json(node);
|
||||
}
|
||||
event_type = node.get_string();
|
||||
|
||||
try {
|
||||
incoming_event(room_id, member_node,
|
||||
Event.new_from_json(event_type,
|
||||
room_id,
|
||||
member_node));
|
||||
} catch (GLib.Error e) {}
|
||||
evt = Matrix.Event.new_from_json(event_type, room_id, event_node);
|
||||
} catch (Matrix.Error e) {
|
||||
warning("Error during event creation: %s", e.message);
|
||||
|
||||
return;
|
||||
} catch (GLib.Error e) {
|
||||
warning("Error during event creation: %s", e.message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
incoming_event(room_id, event_node, evt);
|
||||
}
|
||||
|
||||
private void
|
||||
cb_event_stream(string content_type,
|
||||
Json.Node? json_content,
|
||||
ByteArray? raw_content,
|
||||
Matrix.Error? error)
|
||||
_process_event_list_obj(Json.Node node, string? room_id)
|
||||
requires(node.get_node_type() == Json.NodeType.OBJECT)
|
||||
{
|
||||
string? end_token = null;
|
||||
Json.Object node_obj;
|
||||
Json.Node events_node;
|
||||
|
||||
node_obj = node.get_object();
|
||||
|
||||
if ((events_node = node_obj.get_member("events")) != null) {
|
||||
if (events_node.get_node_type() == Json.NodeType.ARRAY) {
|
||||
events_node.get_array().foreach_element(
|
||||
(array, idx, event_node) => {
|
||||
process_event(event_node, room_id);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void
|
||||
cb_sync(string content_type,
|
||||
Json.Node? json_content,
|
||||
ByteArray? raw_content,
|
||||
Matrix.Error? error)
|
||||
{
|
||||
if (error == null) {
|
||||
var root_obj = json_content.get_object();
|
||||
Json.Node? node;
|
||||
|
||||
if ((node = root_obj.get_member("chunk")) != null) {
|
||||
var chunks = node.get_array();
|
||||
debug("Processing account data");
|
||||
_process_event_list_obj(root_obj.get_member("account_data"),
|
||||
null);
|
||||
|
||||
chunks.foreach_element(
|
||||
(ary, idx, member_node) => process_event(ary, idx, member_node));
|
||||
debug("Processing presence");
|
||||
_process_event_list_obj(root_obj.get_member("presence"),
|
||||
null);
|
||||
|
||||
if ((node = root_obj.get_member("rooms")) != null) {
|
||||
if (node.get_node_type() == Json.NodeType.OBJECT) {
|
||||
Json.Object rooms_object = node.get_object();
|
||||
Json.Node rooms_node;
|
||||
|
||||
debug("Processing rooms");
|
||||
|
||||
if ((rooms_node = rooms_object.get_member(
|
||||
"invite")) != null) {
|
||||
rooms_node.get_object().foreach_member(
|
||||
(obj, room_id, room_node) => {
|
||||
if (room_node.get_node_type() != Json.NodeType.OBJECT) {
|
||||
return;
|
||||
}
|
||||
|
||||
_process_event_list_obj(
|
||||
room_node
|
||||
.get_object()
|
||||
.get_member("invite_state"),
|
||||
room_id);
|
||||
});
|
||||
}
|
||||
|
||||
if ((rooms_node = rooms_object.get_member(
|
||||
"join")) != null) {
|
||||
rooms_node.get_object().foreach_member(
|
||||
(obj, room_id, room_node) => {
|
||||
if (room_node.get_node_type() != Json.NodeType.OBJECT) {
|
||||
return;
|
||||
}
|
||||
|
||||
_process_event_list_obj(
|
||||
room_node
|
||||
.get_object()
|
||||
.get_member("timeline"),
|
||||
room_id);
|
||||
_process_event_list_obj(
|
||||
room_node
|
||||
.get_object()
|
||||
.get_member("state"),
|
||||
room_id);
|
||||
_process_event_list_obj(
|
||||
room_node
|
||||
.get_object()
|
||||
.get_member("account_data"),
|
||||
room_id);
|
||||
_process_event_list_obj(
|
||||
room_node
|
||||
.get_object()
|
||||
.get_member("ephemeral"),
|
||||
room_id);
|
||||
});
|
||||
}
|
||||
|
||||
if ((rooms_node = rooms_object.get_member(
|
||||
"leave")) != null) {
|
||||
rooms_node.get_object().foreach_member(
|
||||
(obj, room_id, room_node) => {
|
||||
if (room_node.get_node_type() != Json.NodeType.OBJECT) {
|
||||
return;
|
||||
}
|
||||
|
||||
_process_event_list_obj(
|
||||
room_node
|
||||
.get_object()
|
||||
.get_member("timeline"),
|
||||
room_id);
|
||||
_process_event_list_obj(
|
||||
room_node
|
||||
.get_object()
|
||||
.get_member("state"),
|
||||
room_id);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((node = root_obj.get_member("end")) != null) {
|
||||
end_token = node.get_string();
|
||||
if ((node = root_obj.get_member("next_batch")) != null) {
|
||||
_last_sync_token = node.get_string();
|
||||
}
|
||||
}
|
||||
|
||||
// Only continue polling if polling is still enabled, and
|
||||
// there was no communication error during the last call
|
||||
|
||||
if (_polling && ((error == null) || (error.code <= 500))) {
|
||||
_polling = false;
|
||||
|
||||
// It is possible that polling has been disabled while we were
|
||||
// processing events. Don’t continue polling if that is the
|
||||
// case.
|
||||
if (_polling) {
|
||||
// This `500` should be changed to M_MISSING_TOKEN somehow
|
||||
try {
|
||||
event_stream(
|
||||
(API.Callback)cb_event_stream,
|
||||
end_token,
|
||||
_event_timeout);
|
||||
} catch (Matrix.Error e) {}
|
||||
} else if ((error != null) && (error.code < 500)) {
|
||||
info("Communication error while reading the event stream. Polling stopped.");
|
||||
try {
|
||||
stop_polling(false);
|
||||
if ((error == null) || (error.code < 500)) {
|
||||
begin_polling();
|
||||
} else if ((error != null) && error.code >= 500) {
|
||||
stop_polling(false);
|
||||
}
|
||||
} catch (Matrix.Error e) {}
|
||||
}
|
||||
}
|
||||
@ -162,11 +253,16 @@ public class Matrix.HTTPClient : Matrix.HTTPAPI, Matrix.Client {
|
||||
throws Matrix.Error
|
||||
{
|
||||
try {
|
||||
event_stream((API.Callback)cb_event_stream, null, _event_timeout);
|
||||
sync((API.Callback)cb_sync,
|
||||
null, null, _last_sync_token,
|
||||
false, false, _event_timeout);
|
||||
|
||||
_polling = true;
|
||||
} catch (Matrix.Error e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
_polling = true;
|
||||
}
|
||||
|
||||
public void
|
||||
|
Loading…
Reference in New Issue
Block a user