forked from cory/tildefriends
Do app -> client communication more like tfrpc so that it's easier to get responses.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3956 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
41590921c3
commit
d70dba021a
74
core/app.js
74
core/app.js
@ -1,7 +1,10 @@
|
|||||||
import * as auth from './auth.js';
|
import * as auth from './auth.js';
|
||||||
import * as core from './core.js';
|
import * as core from './core.js';
|
||||||
|
|
||||||
var gSessionIndex = 0;
|
let g_next_id = 1;
|
||||||
|
let g_calls = {};
|
||||||
|
|
||||||
|
let gSessionIndex = 0;
|
||||||
|
|
||||||
function makeSessionId() {
|
function makeSessionId() {
|
||||||
return (gSessionIndex++).toString();
|
return (gSessionIndex++).toString();
|
||||||
@ -19,31 +22,45 @@ App.prototype.readOutput = function(callback) {
|
|||||||
|
|
||||||
App.prototype.makeFunction = function(api) {
|
App.prototype.makeFunction = function(api) {
|
||||||
let self = this;
|
let self = this;
|
||||||
|
let id = g_next_id++;
|
||||||
|
while (!id || g_calls[id]) {
|
||||||
|
id = g_next_id++;
|
||||||
|
}
|
||||||
|
let promise = new Promise(function(resolve, reject) {
|
||||||
|
g_calls[id] = {resolve: resolve, reject: reject};
|
||||||
|
});
|
||||||
let result = function() {
|
let result = function() {
|
||||||
let message = {action: api[0]};
|
let message = {
|
||||||
for (let i = 1; i < api.length; i++) {
|
message: 'tfrpc',
|
||||||
message[api[i]] = arguments[i - 1];
|
method: api[0],
|
||||||
}
|
params: [...arguments],
|
||||||
|
id: id,
|
||||||
|
};
|
||||||
self.send(message);
|
self.send(message);
|
||||||
|
return promise;
|
||||||
};
|
};
|
||||||
Object.defineProperty(result, 'name', {value: api[0], writable: false});
|
Object.defineProperty(result, 'name', {value: api[0], writable: false});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
App.prototype.send = function(message) {
|
App.prototype.send = function(message) {
|
||||||
if (message) {
|
if (this._send_queue) {
|
||||||
this._send_queue.push(message);
|
if (this._on_output) {
|
||||||
|
this._send_queue.forEach(x => this._on_output(x));
|
||||||
|
this._send_queue = null;
|
||||||
|
} else if (message) {
|
||||||
|
this._send_queue.push(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (this._on_output) {
|
if (message && this._on_output) {
|
||||||
this._send_queue.forEach(message => this._on_output(message));
|
this._on_output(message);
|
||||||
this._send_queue = [];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function socket(request, response, client) {
|
function socket(request, response, client) {
|
||||||
var process;
|
let process;
|
||||||
var options = {};
|
let options = {};
|
||||||
var credentials = auth.query(request.headers);
|
let credentials = auth.query(request.headers);
|
||||||
|
|
||||||
response.onClose = async function() {
|
response.onClose = async function() {
|
||||||
if (process && process.task) {
|
if (process && process.task) {
|
||||||
@ -59,7 +76,7 @@ function socket(request, response, client) {
|
|||||||
|
|
||||||
response.onMessage = async function(event) {
|
response.onMessage = async function(event) {
|
||||||
if (event.opCode == 0x1 || event.opCode == 0x2) {
|
if (event.opCode == 0x1 || event.opCode == 0x2) {
|
||||||
var message;
|
let message;
|
||||||
try {
|
try {
|
||||||
message = JSON.parse(event.data);
|
message = JSON.parse(event.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -67,11 +84,11 @@ function socket(request, response, client) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (message.action == "hello") {
|
if (message.action == "hello") {
|
||||||
var packageOwner;
|
let packageOwner;
|
||||||
var packageName;
|
let packageName;
|
||||||
var blobId;
|
let blobId;
|
||||||
var match;
|
let match;
|
||||||
var parentApp;
|
let parentApp;
|
||||||
if (match = /^\/([&%][^\.]{44}(?:\.\w+)?)(\/?.*)/.exec(message.path)) {
|
if (match = /^\/([&%][^\.]{44}(?:\.\w+)?)(\/?.*)/.exec(message.path)) {
|
||||||
blobId = match[1];
|
blobId = match[1];
|
||||||
} else if (match = /^\/\~([^\/]+)\/([^\/]+)\/$/.exec(message.path)) {
|
} else if (match = /^\/\~([^\/]+)\/([^\/]+)\/$/.exec(message.path)) {
|
||||||
@ -83,7 +100,7 @@ function socket(request, response, client) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (packageOwner != 'core') {
|
if (packageOwner != 'core') {
|
||||||
var coreId = await new Database('core').get('path:' + packageName);
|
let coreId = await new Database('core').get('path:' + packageName);
|
||||||
parentApp = {
|
parentApp = {
|
||||||
path: '/~core/' + packageName + '/',
|
path: '/~core/' + packageName + '/',
|
||||||
id: coreId,
|
id: coreId,
|
||||||
@ -101,7 +118,7 @@ function socket(request, response, client) {
|
|||||||
options.credentials = credentials;
|
options.credentials = credentials;
|
||||||
options.packageOwner = packageOwner;
|
options.packageOwner = packageOwner;
|
||||||
options.packageName = packageName;
|
options.packageName = packageName;
|
||||||
var sessionId = makeSessionId();
|
let sessionId = makeSessionId();
|
||||||
if (blobId) {
|
if (blobId) {
|
||||||
process = await core.getSessionProcessBlob(blobId, sessionId, options);
|
process = await core.getSessionProcessBlob(blobId, sessionId, options);
|
||||||
}
|
}
|
||||||
@ -112,9 +129,9 @@ function socket(request, response, client) {
|
|||||||
process.app.send();
|
process.app.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
var ping = function() {
|
let ping = function() {
|
||||||
var now = Date.now();
|
let now = Date.now();
|
||||||
var again = true;
|
let again = true;
|
||||||
if (now - process.lastActive < process.timeout) {
|
if (now - process.lastActive < process.timeout) {
|
||||||
// Active.
|
// Active.
|
||||||
} else if (process.lastPing > process.lastActive) {
|
} else if (process.lastPing > process.lastActive) {
|
||||||
@ -143,6 +160,15 @@ function socket(request, response, client) {
|
|||||||
}
|
}
|
||||||
} else if (message.action == 'permission') {
|
} else if (message.action == 'permission') {
|
||||||
core.setPermission(process, message.id, message.granted);
|
core.setPermission(process, message.id, message.granted);
|
||||||
|
} else if (message.message == 'tfrpc') {
|
||||||
|
if (message.id && g_calls[message.id]) {
|
||||||
|
if (message.error !== undefined) {
|
||||||
|
g_calls[message.id].reject(message.error);
|
||||||
|
} else {
|
||||||
|
g_calls[message.id].resolve(message.result);
|
||||||
|
}
|
||||||
|
delete g_calls[message.id];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (process && process.eventHandlers['message']) {
|
if (process && process.eventHandlers['message']) {
|
||||||
await core.invoke(process.eventHandlers['message'], [message]);
|
await core.invoke(process.eventHandlers['message'], [message]);
|
||||||
|
@ -438,7 +438,7 @@ function api_localStorageSet(key, value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function api_localStorageGet(key, value) {
|
function api_localStorageGet(key, value) {
|
||||||
send({message: 'localStorage', key: key, value: window.localStorage.getItem('app:' + key)});
|
return window.localStorage.getItem('app:' + key);
|
||||||
}
|
}
|
||||||
|
|
||||||
function api_requestPermission(permission, id) {
|
function api_requestPermission(permission, id) {
|
||||||
@ -594,10 +594,24 @@ function receive(message) {
|
|||||||
}
|
}
|
||||||
timeseries.append(now, message.stats[key]);
|
timeseries.append(now, message.stats[key]);
|
||||||
}
|
}
|
||||||
} else if (message && message.action) {
|
} else if (message &&
|
||||||
let api = k_api[message.action];
|
message.message === 'tfrpc' &&
|
||||||
|
message.method) {
|
||||||
|
let api = k_api[message.method];
|
||||||
if (api) {
|
if (api) {
|
||||||
api.func(...api.args.map(x => message[x]));
|
Promise.resolve(api.func(...message.params)).then(function(result) {
|
||||||
|
send({
|
||||||
|
message: 'tfrpc',
|
||||||
|
id: message.id,
|
||||||
|
result: result,
|
||||||
|
});
|
||||||
|
}).catch(function(error) {
|
||||||
|
send({
|
||||||
|
message: 'tfrpc',
|
||||||
|
id: message.id,
|
||||||
|
error: error,
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,9 @@ if (k_is_browser) {
|
|||||||
function make_rpc(target, prop, receiver) {
|
function make_rpc(target, prop, receiver) {
|
||||||
return function() {
|
return function() {
|
||||||
let id = g_next_id++;
|
let id = g_next_id++;
|
||||||
|
while (!id || g_calls[id]) {
|
||||||
|
id = g_next_id++;
|
||||||
|
}
|
||||||
let promise = new Promise(function(resolve, reject) {
|
let promise = new Promise(function(resolve, reject) {
|
||||||
g_calls[id] = {resolve: resolve, reject: reject};
|
g_calls[id] = {resolve: resolve, reject: reject};
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user