/pidgin/main: 313fc6c8f415: facebook: implemented queued message...
James Geboski <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: 313fc6c8f4153ce6c9388aa029da565949136711 Author: James Geboski <[email protected]> Date: 2016-01-04 17:17 -0500 Branch: default URL: https://hg.pidgin.im/pidgin/main/rev/313fc6c8f415 Description: facebook: implemented queued message sending This ensures a message is sent successfully before attempting to send another message. As a result, messages are sent in their proper order, instead of the order in which they arrive. This also introduces a check for the successful sending of a message, rather than silently failing. The queued sending also ensures messages are not lost when the state of visibility is being switched. This also allows the plugin to silently reconnect when a connection failure occurs. diffstat: libpurple/protocols/facebook/api.c | 134 +++++++++++++++++++++++++++--------- 1 files changed, 101 insertions(+), 33 deletions(-) diffs (225 lines): diff --git a/libpurple/protocols/facebook/api.c b/libpurple/protocols/facebook/api.c --- a/libpurple/protocols/facebook/api.c +++ b/libpurple/protocols/facebook/api.c @@ -63,7 +63,7 @@ struct _FbApiPrivate gchar *stoken; gchar *token; - GHashTable *mids; + GQueue *msgs; gboolean invisible; guint unread; @@ -82,6 +82,9 @@ static void fb_api_contacts_after(FbApi *api, const gchar *writeid); static void +fb_api_message_send(FbApi *api, FbApiMessage *msg); + +static void fb_api_sticker(FbApi *api, FbId sid, FbApiMessage *msg); G_DEFINE_TYPE(FbApi, fb_api, G_TYPE_OBJECT); @@ -175,7 +178,7 @@ fb_api_dispose(GObject *obj) fb_http_conns_free(priv->cons); g_hash_table_destroy(priv->data); - g_hash_table_destroy(priv->mids); + g_queue_free_full(priv->msgs, (GDestroyNotify) fb_api_message_free); g_free(priv->cid); g_free(priv->did); @@ -485,10 +488,9 @@ fb_api_init(FbApi *api) api->priv = priv; priv->cons = fb_http_conns_new(); + priv->msgs = g_queue_new(); priv->data = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); - priv->mids = g_hash_table_new_full(g_int64_hash, g_int64_equal, - g_free, NULL); } GQuark @@ -938,6 +940,7 @@ fb_api_cb_mqtt_open(FbMqtt *mqtt, gpoint static void fb_api_connect_queue(FbApi *api) { + FbApiMessage *msg; FbApiPrivate *priv = api->priv; gchar *json; JsonBuilder *bldr; @@ -984,6 +987,10 @@ fb_api_connect_queue(FbApi *api) g_signal_emit_by_name(api, "connect"); g_free(json); + if (!g_queue_is_empty(priv->msgs)) { + msg = g_queue_peek_head(priv->msgs); + fb_api_message_send(api, msg); + } } static void @@ -1262,6 +1269,47 @@ fb_api_cb_publish_typing(FbApi *api, GBy json_node_free(root); } +static void +fb_api_cb_publish_ms_r(FbApi *api, GByteArray *pload) +{ + FbApiMessage *msg; + FbApiPrivate *priv = api->priv; + FbJsonValues *values; + GError *err = NULL; + JsonNode *root; + + if (!fb_api_json_chk(api, pload->data, pload->len, &root)) { + return; + } + + values = fb_json_values_new(root); + fb_json_values_add(values, FB_JSON_TYPE_BOOL, TRUE, "$.succeeded"); + fb_json_values_update(values, &err); + + FB_API_ERROR_EMIT(api, err, + g_object_unref(values); + json_node_free(root); + return; + ); + + if (fb_json_values_next_bool(values, TRUE)) { + /* Pop and free the successful message */ + msg = g_queue_pop_head(priv->msgs); + fb_api_message_free(msg); + + if (!g_queue_is_empty(priv->msgs)) { + msg = g_queue_peek_head(priv->msgs); + fb_api_message_send(api, msg); + } + } else { + fb_api_error(api, FB_API_ERROR_GENERAL, + "Failed to send message"); + } + + g_object_unref(values); + json_node_free(root); +} + static gchar * fb_api_xma_parse(FbApi *api, const gchar *body, JsonNode *root, GError **error) { @@ -1432,9 +1480,6 @@ fb_api_cb_publish_ms(FbApi *api, GByteAr values = fb_json_values_new(root); fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE, - "$.deltaNewMessage.messageMetadata" - ".offlineThreadingId"); - fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE, "$.deltaNewMessage.messageMetadata.actorFbId"); fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE, "$.deltaNewMessage.messageMetadata" @@ -1453,12 +1498,6 @@ fb_api_cb_publish_ms(FbApi *api, GByteAr fb_json_values_set_array(values, TRUE, "$.deltas"); while (fb_json_values_update(values, &err)) { - id = fb_json_values_next_int(values, 0); - - if (g_hash_table_remove(priv->mids, &id)) { - continue; - } - fb_api_message_reset(&msg, FALSE); msg.uid = fb_json_values_next_int(values, 0); oid = fb_json_values_next_int(values, 0); @@ -1646,6 +1685,7 @@ fb_api_cb_mqtt_publish(FbMqtt *mqtt, con {"/mark_thread_response", fb_api_cb_publish_mark}, {"/mercury", fb_api_cb_publish_mercury}, {"/orca_typing_notifications", fb_api_cb_publish_typing}, + {"/send_message_response", fb_api_cb_publish_ms_r}, {"/t_ms", fb_api_cb_publish_ms}, {"/t_p", fb_api_cb_publish_p} }; @@ -2119,35 +2159,63 @@ fb_api_disconnect(FbApi *api) fb_mqtt_disconnect(priv->mqtt); } +static void +fb_api_message_send(FbApi *api, FbApiMessage *msg) +{ + const gchar *tpfx; + FbApiPrivate *priv = api->priv; + FbId id; + FbId mid; + gchar *json; + JsonBuilder *bldr; + + mid = FB_API_MSGID(g_get_real_time() / 1000, g_random_int()); + + if (msg->tid != 0) { + tpfx = "tfbid_"; + id = msg->tid; + } else { + tpfx = ""; + id = msg->uid; + } + + bldr = fb_json_bldr_new(JSON_NODE_OBJECT); + fb_json_bldr_add_str(bldr, "body", msg->text); + fb_json_bldr_add_strf(bldr, "msgid", "%" FB_ID_FORMAT, mid); + fb_json_bldr_add_strf(bldr, "sender_fbid", "%" FB_ID_FORMAT, priv->uid); + fb_json_bldr_add_strf(bldr, "to", "%s%" FB_ID_FORMAT, tpfx, id); + + json = fb_json_bldr_close(bldr, JSON_NODE_OBJECT, NULL); + fb_api_publish(api, "/send_message2", "%s", json); + g_free(json); +} + void fb_api_message(FbApi *api, FbId id, gboolean thread, const gchar *text) { - const gchar *tpfx; + FbApiMessage *msg; FbApiPrivate *priv; - FbId *dmid; - FbId mid; - gchar *json; - JsonBuilder *bldr; + gboolean empty; g_return_if_fail(FB_IS_API(api)); g_return_if_fail(text != NULL); priv = api->priv; - mid = FB_API_MSGID(g_get_real_time() / 1000, g_random_int()); - tpfx = thread ? "tfbid_" : ""; - - dmid = g_memdup(&mid, sizeof mid); - g_hash_table_replace(priv->mids, dmid, dmid); - - bldr = fb_json_bldr_new(JSON_NODE_OBJECT); - fb_json_bldr_add_str(bldr, "body", text); - fb_json_bldr_add_strf(bldr, "msgid", "%" FB_ID_FORMAT, mid); - fb_json_bldr_add_strf(bldr, "sender_fbid", "%" FB_ID_FORMAT, priv->uid); - fb_json_bldr_add_strf(bldr, "to", "%s%" FB_ID_FORMAT, tpfx, id); - - json = fb_json_bldr_close(bldr, JSON_NODE_OBJECT, NULL); - fb_api_publish(api, "/send_message2", "%s", json); - g_free(json); + msg = fb_api_message_dup(NULL, FALSE); + msg->text = g_strdup(text); + + if (thread) { + msg->tid = id; + } else { + msg->uid = id; + } + + empty = g_queue_is_empty(priv->msgs); + g_queue_push_tail(priv->msgs, msg); + + if (empty && fb_mqtt_connected(priv->mqtt, FALSE)) { + fb_api_message_send(api, msg); + } } void _______________________________________________ Commits mailing list [email protected] https://pidgin.im/cgi-bin/mailman/listinfo/commits