Add the Client.send() method

This commit is contained in:
Gergely Polonkai 2016-03-19 08:12:13 +01:00
parent 161c171144
commit 734a8349d0
2 changed files with 107 additions and 0 deletions

View File

@ -217,4 +217,34 @@ public interface Matrix.Client : GLib.Object {
public abstract Room
get_room_by_alias(string room_alias)
throws Matrix.Error;
/**
* Callback type for {@link Matrix.Client.send}.
*
* @param event_id the event_id returned by the server
* @param err an error raised during event sending, if any
*/
public delegate void
SendCallback(string? event_id, GLib.Error? err);
/**
* Send an event to the given room. This will use the
* /room/{roomId}/send or /room/{roomId}/state API depending on
* the event: if the event has a state key (there is a state_key
* key in the generated JSON), even if an empty one, it will use
* the latter.
*
* @param room_id the room to send the event to
* @param evt the event to send
* @param cb the callback function to call when the request is
* finished
* @param txn_id the transaction ID used by this request. In case
* of a state event, it will be untouched
*/
public abstract void
send(string room_id,
Matrix.Event.Base evt,
SendCallback? cb,
out ulong txn_id)
throws Matrix.Error;
}

View File

@ -30,6 +30,7 @@ public class Matrix.HTTPClient : Matrix.HTTPAPI, Matrix.Client {
new Gee.HashMap<string, Presence>();
private Gee.HashMap<string, Room> _rooms =
new Gee.HashMap<string, Room>();
private ulong _last_txn_id = 0;
public
HTTPClient(string base_url)
@ -487,4 +488,80 @@ public class Matrix.HTTPClient : Matrix.HTTPAPI, Matrix.Client {
throw new Matrix.Error.UNAVAILABLE(
"Noo room data found for alias %s", room_alias);
}
/**
* Get the next transaction ID to use. It increments the
* internally stored value and returns that, so it is guaranteed
* to be unique until we run out of ulong boundaries.
*
* It is called internally by send().
*/
public ulong
next_txn_id()
{
return ++_last_txn_id;
}
private void
send_callback(Json.Node? json_content,
GLib.Error? err,
Matrix.Client.SendCallback? cb)
{
string? event_id = null;
GLib.Error? new_err = err;
// If there is no callback, there is no point to continue
if (cb == null) {
return;
}
if (err == null) {
var root = json_content.get_object();
if (root.has_member("event_id")) {
event_id = root.get_string_member("event_id");
} else {
new_err = new Matrix.Error.BAD_RESPONSE(
"event_id is missing from an event response");
}
}
cb(event_id, new_err);
}
public void
send(string room_id,
Matrix.Event.Base evt,
Matrix.Client.SendCallback? cb,
out ulong txn_id)
throws Matrix.Error
{
var evt_node = evt.json;
var evt_root = evt_node.get_object();
string? state_key = null;
if (evt_root.has_member("state_key")) {
state_key = evt_root.get_string_member("state_key");
}
if (state_key != null) {
txn_id = 0;
send_state_event(
(i, ct, json_node, rc, err) =>
send_callback(json_node, err, cb),
room_id,
evt.event_type,
(state_key == "") ? null : state_key,
evt_root.get_member("content"));
} else {
txn_id = next_txn_id();
send_event(
(i, ct, json_node, rc, err) =>
send_callback(json_node, err, cb),
room_id,
evt.event_type,
"%lu".printf(txn_id),
evt_root.get_member("content"));
}
}
}