Skip to content
This repository was archived by the owner on May 24, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions packages/fether-electron/src/main/app/ipcChannel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,25 @@ class IpcChannel extends EventEmitter {
this._sendQueued();
resolve(true);
});

// We get data from the socket by chunks, and 1 chunk !== 1 Rpc message
// Sometimes 1 chunk is multiple messages, sometimes we get partial
// messages.
// https://github.com/paritytech/fether/issues/562

// The last element in a '\n'-separate chunk. Will be `""` if the
// last element was a correctly-formed message, or will hold the
// ill-formed message otherwise.
let lastData = '';
socket.on('data', data_ => {
const data = data_.toString();
// Sometimes we receive multiple messages at once
const messages = data.split(/\r?\n/).filter(Boolean);
// If the last data was truncated, then we concatenate to the new data
// we just received
const data = `${lastData}${data_.toString()}`;

// All messages are separated by a '\n'
const messages = data.split(/\n/);
lastData = messages.pop(); // Will hold "" or an ill-formed JSONRPC message

messages.forEach(data => {
this.emit('message', data);
});
Expand Down
44 changes: 39 additions & 5 deletions packages/fether-react/src/utils/PostMessageProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

import * as postMessage from './postMessage';
import EventEmitter from 'eventemitter3';

import Debug from './debug';
import * as postMessage from './postMessage';

const debug = Debug('PostMessageProvider');

export default class PostMessageProvider extends EventEmitter {
constructor (destination, source) {
constructor (destination) {
super();

this._destination = destination || window.parent;
Expand Down Expand Up @@ -136,20 +140,50 @@ export default class PostMessageProvider extends EventEmitter {
}

_receiveMessage (raw) {
const parsed = JSON.parse(raw);
let parsed;
try {
parsed = JSON.parse(raw);
} catch (err) {
// Should not happen anymore, since the following issue is fixed
// https://github.com/paritytech/fether/issues/562
debug(`Cannot parse ${raw}. Ignoring message.`);

return;
}

const { id, error } = parsed;
const subscription = parsed.params && parsed.params.subscription;

if (subscription) {
// subscription notification
const result = parsed.params.result;
let messageId = this._subscriptionsToId[subscription];
this._messages[messageId].callback(error && new Error(error), result);

// Sometimes we receive results for a subscription that we have never
// seen before. Should not happen.
if (!this._messages[messageId]) {
debug(`Got result for unknown subscription ${subscription}`);

return;
}

this._messages[messageId].callback(
error && new Error(error.message),
result
);
} else {
// Sometimes we receive results for an id that we have never seen before.
// Should not happen.
if (!this._messages[id]) {
debug(`Got result for unknown id ${id}`);

return;
}

// request response
const result = parsed.result;
if (error) {
this._messages[id].reject(new Error(error));
this._messages[id].reject(new Error(error.message));
} else {
this._messages[id].resolve(result);

Expand Down