ForgeTotal.js 5
de

Total.js 5

OPENCLIENT RPC, Veranstaltungen und gemeinsame Verbindungen

Total.js 5 · total5@0.0.19 total5reference Mit Total.js 5 ausgeführt

OPENCLIENT(url, [id]) ist der native Client des Open-Platform-Protokolls. Er wandelt http/https-URLs in ws/wss um. Logische Clients mit derselben URL teilen sich einen WebSocket. .online(fn) erhält die Metadaten {type:'init',id:...} des Servers; .message(fn) erhält unaufgeforderte Nachrichten. .rpc(message) gibt ein Promise zurück; .send(message, callback, [filter], [timeoutMs]) verwendet einen Callback; .cmd(message) sendet ohne zu warten. .remove() schließt den physischen Socket erst, nachdem sein letzter logischer Client entfernt wurde.

Das Beispiel umfasst einen lokalen Protokollserver. callbackid, error und response sind Protokollefelder. Eine Callback-Timout ist opt-in; Set one für Anfragen, die eine Frist benötigen.

controllers/open.js
exports.install = function() {
	ROUTE('SOCKET /fixture/', fixture);
	ROUTE('GET /openclient/', exercise);
};
function fixture() {
	var server = this;
	server.on('open', function(client) {
		client.send({ type: 'init', id: 'local-fixture', version: 1 });
	});
	server.on('message', function(client, message) {
		if (message.type === 'ignore')
			return;
		if (message.type === 'event') {
			client.send({ type: 'notice', value: message.value });
			return;
		}
		client.send({ callbackid: message.callbackid, error: message.type === 'fail' ? 'denied' : null, response: { value: message.value } });
	});
}
async function exercise($) {
	var a;
	var b;
	try {
		var url = $.hostname('/fixture/');
		a = OPENCLIENT(url, 'first');
		await new Promise(function(resolve, reject) {
			var timer = setTimeout(() => reject(new Error('init deadline')), 2000);
			a.online(function(meta) { if (meta) { clearTimeout(timer); resolve(); } });
		});
		b = OPENCLIENT(url, 'second');
		var shared = a.ws === b.ws;
		var sum = await a.rpc({ type: 'echo', value: 7 });
		var event = new Promise(resolve => a.message(resolve));
		a.cmd({ type: 'event', value: 9 });
		var notice = await event;
		var denied = await new Promise(resolve => a.send({ type: 'fail' }, err => resolve(String(err)), 300));
		var timeout = await new Promise(resolve => a.send({ type: 'ignore' }, err => resolve(String(err)), 50));
		a.remove();
		a = null;
		var alive = await b.rpc({ type: 'echo', value: 11 });
		var meta = b.meta;
		b.remove();
		b = null;
		$.json({ shared: shared, sum: sum, notice: notice, denied: denied, timeout: timeout, alive: alive, meta: meta });
	} catch (e) { $.invalid(e); }
	finally { if (a) a.remove(); if (b) b.remove(); }
}