implement basic clientside RPC infrastructure

and provide a basic example for testing it
pull/1/head
ansuz 8 years ago
parent 612a00b484
commit b3cc8da315

@ -3,26 +3,73 @@ define([
'/bower_components/tweetnacl/nacl-fast.min.js',
], function (Encode) {
var MAX_LAG_BEFORE_TIMEOUT = 30000;
var getHistoryKeeperName = function (network) {
var wc = network.webChannels[0];
if (!wc) {
throw new Error("ERROR: no joined webchannels so we can't get the history keeper name");
}
if (!wc.history_keeper) { throw new Error("ERROR: no history keeper"); }
return wc.history_keeper;
var uid = function () {
return Number(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER))
.toString(32).replace(/\./g, '');
};
var sendMsg = function (ctx, cb) {
var hkn = getHistoryKeeperName(ctx.network);
/*
types of messages:
pin -> hash
unpin -> hash
getHash -> hash
getTotalSize -> bytes
getFileSize -> bytes
*/
/* RPC communicates only with the history keeper
messages have the format:
[TYPE, txid, msg]
*/
var sendMsg = function (ctx, type, msg, cb) {
var network = ctx.network;
var hkn = network.historyKeeper;
var txid = uid();
ctx.pending[txid] = cb;
return network.sendto(hkn, JSON.stringify([txid, type, msg]));
};
var parse = function (msg) {
try {
return JSON.parse(msg);
} catch (e) {
return null;
}
};
/* Returning messages have the format:
[txid, {}]
*/
var onMsg = function (ctx, msg) {
var parsed = parse(msg);
if (!parsed) {
// TODO handle error
console.log(msg);
return;
}
var txid = parsed[0];
var pending = ctx.pending[txid];
var response = parsed.slice(1);
if (typeof(pending) === 'function') {
if (response[0] === 'ERROR') {
return void pending(response[1]);
}
pending(void 0, response);
} else {
console.log("No callback provided");
}
};
var cookie = function (ctx, cb) {
// TODO
// TODO txid
};
var signMsg = function (msg, secKey) {
@ -31,16 +78,27 @@ define([
var create = function (network, edPrivateKey) {
if (!/[0-9a-f]{64}/.test(edPrivateKey)) {
throw new Error("private signing key is not valid");
//throw new Error("private signing key is not valid");
}
var ctx = {
privateKey: Encode.hexToUint8Array(edPrivateKey),
//privateKey: Encode.hexToUint8Array(edPrivateKey),
seq: new Date().getTime(),
network: network
network: network,
timeouts: {}, // timeouts
pending: {}, // callbacks
};
var pin = function (channel, cb) { };
var send = function (type, msg, cb) {
return sendMsg(ctx, type, msg, cb);
};
network.on('message', function (msg) { onMsg(ctx, msg); });
network.on('message', function (msg, sender) {
onMsg(ctx, msg);
});
return {
cookie: function (cb) { cookie(ctx, cb); },
send: send,
};
};

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html class="cp slide">
<head>
<title>CryptPad</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
</head>
<body>
<div id="iframe-container">
<iframe id="pad-iframe"></iframe><script src="/common/noscriptfix.js"></script>
</div>
</body>
</html>

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<h1>PEWPEW

@ -0,0 +1,35 @@
require.config({ paths: { 'json.sortify': '/bower_components/json.sortify/dist/JSON.sortify' } });
define([
'/common/cryptpad-common.js',
'/common/rpc.js',
'/bower_components/jquery/dist/jquery.min.js',
], function (Cryptpad, RPC) {
var $ = window.jQuery;
var APP = window.APP = {
Cryptpad: Cryptpad,
};
$(function () {
Cryptpad.ready(function (err, env) {
var network = Cryptpad.getNetwork();
var rpc = RPC.create(network); // TODO signing key
var payload = {
a: Math.floor(Math.random() * 1000),
b: 7,
};
// console.log(payload);
rpc.send('ECHO', payload, function (e, msg) {
if (e) { return void console.error(e); }
console.log(msg);
});
// test a non-existent RPC call
rpc.send('PEWPEW', ['pew'], function (e, msg) {
if (e) { return void console.error(e); }
console.log(msg);
});
});
});
});
Loading…
Cancel
Save