react-native/local-cli/server/util/jsPackagerClient.js

116 lines
3.0 KiB
JavaScript

/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
'use strict';
const WebSocket = require('ws');
const parseMessage = require('./messageSocket').parseMessage;
const PROTOCOL_VERSION = 2;
const TARGET_SERVER = 'server';
function getMessageId() {
return `${Date.now()}:${Math.random()}`;
}
class JsPackagerClient {
constructor(url) {
this.ws = new WebSocket(url);
this.msgCallbacks = new Map();
this.openPromise = new Promise((resolve, reject) => {
this.ws.on('error', error => reject(error));
this.ws.on('open', resolve);
});
this.ws.on('message', (data, flags) => {
const message = parseMessage(data, flags.binary);
const msgCallback = this.msgCallbacks.get(message.id);
if (message === undefined || message.id === undefined) {
// gracefully ignore wrong messages or broadcasts
} else if (msgCallback === undefined) {
console.warn(`Response with non-existing message id: '${message.id}'`);
} else {
if (message.error === undefined) {
msgCallback.resolve(message.result);
} else {
msgCallback.reject(message.error);
}
}
});
}
sendRequest(method, target, params) {
return this.openPromise.then(() => new Promise((resolve, reject) => {
const messageId = getMessageId();
this.msgCallbacks.set(messageId, {resolve: resolve, reject: reject});
this.ws.send(
JSON.stringify({
version: PROTOCOL_VERSION,
target: target,
method: method,
id: messageId,
params: params,
}),
error => {
if (error !== undefined) {
this.msgCallbacks.delete(messageId);
reject(error);
}
});
}));
}
sendNotification(method, target, params) {
return this.openPromise.then(() => new Promise((resolve, reject) => {
this.ws.send(
JSON.stringify({
version: PROTOCOL_VERSION,
target: target,
method: method,
params: params,
}),
error => {
if (error !== undefined) {
reject(error);
} else {
resolve();
}
});
}));
}
sendBroadcast(method, params) {
return this.sendNotification(method, undefined, params);
}
getPeers() {
return new Promise((resolve, reject) => {
this.sendRequest('getpeers', TARGET_SERVER, undefined).then(
response => {
if (!response instanceof Map) {
reject('Results received from server are of wrong format:\n' +
JSON.stringify(response));
} else {
resolve(response);
}
},
reject);
});
}
getId() {
return this.sendRequest('getid', TARGET_SERVER, undefined);
}
}
module.exports = JsPackagerClient;