Skip to content

Instantly share code, notes, and snippets.

@iadvize
Created November 25, 2010 18:36
Show Gist options
  • Save iadvize/715772 to your computer and use it in GitHub Desktop.
Save iadvize/715772 to your computer and use it in GitHub Desktop.

Revisions

  1. Jonathan Gueron revised this gist Jan 6, 2011. 1 changed file with 23 additions and 8 deletions.
    31 changes: 23 additions & 8 deletions strophe.receipts.js
    Original file line number Diff line number Diff line change
    @@ -2,8 +2,8 @@ Strophe.addConnectionPlugin('receipts', {
    _conn: null,
    _msgQueue: {},
    _retries: {},
    _resendCount: 3,
    _resendTime: 3000,
    _resendCount: 10,
    _resendTime: 9000,

    init: function(conn) {
    this._conn = conn;
    @@ -15,7 +15,8 @@ Strophe.addConnectionPlugin('receipts', {
    if (status === Strophe.Status.CONNECTED || status === Strophe.Status.ATTACHED) {
    // set up handlers for receipts
    //this._conn.addHandler(this._onRequestReceived.bind(this), Strophe.NS.RECEIPTS, "message");
    this.resendQueue();
    var that = this;
    setTimeout(function(){that.resendQueue();},5000);
    }
    },

    @@ -58,12 +59,21 @@ Strophe.addConnectionPlugin('receipts', {
    var that = this;
    setTimeout(function(){
    if (that._msgQueue[id]){
    // if we are disconnected, dont increment retries count and retry later
    if (!that._conn.connected) {
    that.resendMessage(id);
    return;
    }
    that._retries[id]++;
    if (that._retries[id] > that._resendCount) {
    //TODO: use mod_rest to force injection of the message
    //console.debug('message could not be delivered after ' + that._resendCount + ' attempts');
    return;
    }
    //console.debug('message was still not received -> RETRYING NOW',that._msgQueue[id]);

    // FIX: use our actual jid in case we disconnected and changed jid
    that._msgQueue[id].tree().setAttribute('from', that._conn.jid);

    that._conn.send(that._msgQueue[id]);
    that.resendMessage(id);
    }
    @@ -117,11 +127,16 @@ Strophe.addConnectionPlugin('receipts', {
    },

    resendQueue: function(){
    if (!this._conn.connected) {
    var that = this;
    setTimeout(function(){that.resendQueue();},5000);
    return;
    }
    for (var id in this._msgQueue) {
    if (this._msgQueue.hasOwnProperty(id)) {
    this._conn.send(this._msgQueue[id]);
    }
    }
    if (this._msgQueue.hasOwnProperty(id)) {
    this._conn.send(this._msgQueue[id]);
    }
    }
    },

    getUnreceivedMsgs: function() {
  2. Jonathan Gueron created this gist Nov 25, 2010.
    140 changes: 140 additions & 0 deletions strophe.receipts.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,140 @@
    Strophe.addConnectionPlugin('receipts', {
    _conn: null,
    _msgQueue: {},
    _retries: {},
    _resendCount: 3,
    _resendTime: 3000,

    init: function(conn) {
    this._conn = conn;
    Strophe.addNamespace('RECEIPTS', 'urn:xmpp:receipts');
    },


    statusChanged: function (status) {
    if (status === Strophe.Status.CONNECTED || status === Strophe.Status.ATTACHED) {
    // set up handlers for receipts
    //this._conn.addHandler(this._onRequestReceived.bind(this), Strophe.NS.RECEIPTS, "message");
    this.resendQueue();
    }
    },

    /*
    _onRequestReceived: function(msg){
    this._processReceipt(msg);
    return true;
    },
    * */

    /* sendMessage
    ** sends a message with a receipt and stores the message in the queue
    ** in case a receipt is never received
    **
    ** msg should be a builder
    */
    sendMessage: function(msg) {
    var id = this._conn.getUniqueId();

    msg.tree().setAttribute('id', id);

    var request = Strophe.xmlElement('request', {'xmlns': Strophe.NS.RECEIPTS});
    msg.tree().appendChild(request);

    this._msgQueue[id] = msg;
    this._retries[id] = 0;

    this._conn.send(msg);

    this.resendMessage(id);

    return id;

    },

    /*
    ** resend queued message
    */
    resendMessage: function(id){
    var that = this;
    setTimeout(function(){
    if (that._msgQueue[id]){
    that._retries[id]++;
    if (that._retries[id] > that._resendCount) {
    //console.debug('message could not be delivered after ' + that._resendCount + ' attempts');
    return;
    }
    //console.debug('message was still not received -> RETRYING NOW',that._msgQueue[id]);
    that._conn.send(that._msgQueue[id]);
    that.resendMessage(id);
    }
    },this._resendTime);
    },

    /* addMessageHandler
    ** add a message handler that handles XEP-0184 message receipts
    */
    addReceiptHandler: function(handler, type, from, options) {
    var that = this;

    var proxyHandler = function(msg) {
    that._processReceipt(msg);

    // call original handler
    return handler(msg);
    };

    this._conn.addHandler(proxyHandler, Strophe.NS.RECEIPTS, 'message',
    type, null, from, options);
    },

    /*
    * process a XEP-0184 message receipts
    * send recept on request
    * remove msg from queue on received
    */
    _processReceipt: function(msg){
    var id = msg.getAttribute('id'),
    from = msg.getAttribute('from'),
    req = msg.getElementsByTagName('request'),
    rec = msg.getElementsByTagName('received');

    // check for request in message
    if (req.length > 0) {
    // send receipt
    var out = $msg({to: from, from: this._conn.jid, id: this._conn.getUniqueId()}),
    request = Strophe.xmlElement('received', {'xmlns': Strophe.NS.RECEIPTS, 'id': id});
    out.tree().appendChild(request);
    this._conn.send(out);
    }
    // check for received
    if (rec.length > 0) {
    var recv_id = rec[0].getAttribute('id');
    if (recv_id) { // delete msg from queue
    delete this._msgQueue[recv_id];
    delete this._retries[recv_id];
    }
    }
    },

    resendQueue: function(){
    for (var id in this._msgQueue) {
    if (this._msgQueue.hasOwnProperty(id)) {
    this._conn.send(this._msgQueue[id]);
    }
    }
    },

    getUnreceivedMsgs: function() {
    var msgs = [];
    for (var id in this._msgQueue) {
    if (this._msgQueue.hasOwnProperty(id)) {
    msgs.push(this._msgQueue[id]);
    }
    }
    return msgs;
    },

    clearMessages: function() {
    this._msgQueue = {};
    }
    });