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 86effb67..24ddcc85 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 9c505730..2d6f39fd 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'); }