From ec6898f1ab0f6703327e5471b7b42cfc29ec1641 Mon Sep 17 00:00:00 2001 From: lilia Date: Mon, 26 Oct 2015 14:16:46 -0700 Subject: [PATCH] Process incoming messages in order This may increase processing latency a bit, particularly with large attachments, but will ensure that messages are dispatched in the order they are received. It would be nice to enforce ordering on only the dispatch step, so that we could, for example, decrypt the next websocket message while waiting for an attachment to download, but that will require a more complicated refactor. Will stick with the quick fix for now and revisit later. Fixes #342 // FREEBIE --- js/libtextsecure.js | 15 ++++++++++----- libtextsecure/message_receiver.js | 15 ++++++++++----- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/js/libtextsecure.js b/js/libtextsecure.js index 86effb679..24ddcc85f 100644 --- a/js/libtextsecure.js +++ b/js/libtextsecure.js @@ -39236,9 +39236,10 @@ MessageReceiver.prototype = { this.socket.onerror = this.onerror.bind(this); this.socket.onopen = this.onopen.bind(this); this.wsr = new WebSocketResource(this.socket, { - handleRequest: this.handleRequest.bind(this), + handleRequest: this.queueRequest.bind(this), keepalive: { path: '/v1/keepalive', disconnect: true } }); + this.pending = Promise.resolve(); }, close: function() { this.wsr.close(); @@ -39262,10 +39263,14 @@ MessageReceiver.prototype = { eventTarget.dispatchEvent(ev); }); }, + queueRequest: function(request) { + var handleRequest = this.handleRequest.bind(this, request); + this.pending = this.pending.then(handleRequest, handleRequest); + }, handleRequest: function(request) { // TODO: handle different types of requests. for now we only expect // PUT /messages - textsecure.crypto.decryptWebsocketMessage(request.body, this.signalingKey).then(function(plaintext) { + return textsecure.crypto.decryptWebsocketMessage(request.body, this.signalingKey).then(function(plaintext) { var envelope = textsecure.protobuf.Envelope.decode(plaintext); // After this point, decoding errors are not the server's // fault, and we should handle them gracefully and tell the @@ -39273,11 +39278,11 @@ MessageReceiver.prototype = { request.respond(200, 'OK'); if (envelope.type === textsecure.protobuf.Envelope.Type.RECEIPT) { - this.onDeliveryReceipt(envelope); + return this.onDeliveryReceipt(envelope); } else if (envelope.content) { - this.handleContentMessage(envelope); + return this.handleContentMessage(envelope); } else if (envelope.legacyMessage) { - this.handleLegacyMessage(envelope); + return this.handleLegacyMessage(envelope); } else { throw new Error('Received message with no content and no legacyMessage'); } diff --git a/libtextsecure/message_receiver.js b/libtextsecure/message_receiver.js index 9c505730c..2d6f39fde 100644 --- a/libtextsecure/message_receiver.js +++ b/libtextsecure/message_receiver.js @@ -26,9 +26,10 @@ MessageReceiver.prototype = { this.socket.onerror = this.onerror.bind(this); this.socket.onopen = this.onopen.bind(this); this.wsr = new WebSocketResource(this.socket, { - handleRequest: this.handleRequest.bind(this), + handleRequest: this.queueRequest.bind(this), keepalive: { path: '/v1/keepalive', disconnect: true } }); + this.pending = Promise.resolve(); }, close: function() { this.wsr.close(); @@ -52,10 +53,14 @@ MessageReceiver.prototype = { eventTarget.dispatchEvent(ev); }); }, + queueRequest: function(request) { + var handleRequest = this.handleRequest.bind(this, request); + this.pending = this.pending.then(handleRequest, handleRequest); + }, handleRequest: function(request) { // TODO: handle different types of requests. for now we only expect // PUT /messages - textsecure.crypto.decryptWebsocketMessage(request.body, this.signalingKey).then(function(plaintext) { + return textsecure.crypto.decryptWebsocketMessage(request.body, this.signalingKey).then(function(plaintext) { var envelope = textsecure.protobuf.Envelope.decode(plaintext); // After this point, decoding errors are not the server's // fault, and we should handle them gracefully and tell the @@ -63,11 +68,11 @@ MessageReceiver.prototype = { request.respond(200, 'OK'); if (envelope.type === textsecure.protobuf.Envelope.Type.RECEIPT) { - this.onDeliveryReceipt(envelope); + return this.onDeliveryReceipt(envelope); } else if (envelope.content) { - this.handleContentMessage(envelope); + return this.handleContentMessage(envelope); } else if (envelope.legacyMessage) { - this.handleLegacyMessage(envelope); + return this.handleLegacyMessage(envelope); } else { throw new Error('Received message with no content and no legacyMessage'); }