ForgeTotal.js 5
pt

Total.js 5

Publique um servidor local através de um túnel com PROXYSERVER() e PROXYCLIENT()

Total.js 5 · total5@0.0.19 proxytunnelwebsocketintegrations Executada com o Total.js 5

PROXY() reencaminha um pedido para um servidor a que o proxy consegue chegar. Um túnel é para o caso contrário: o programa está num portátil ou atrás de uma firewall, pelo que ninguém se consegue ligar a ele, mas ele consegue ligar-se para fora. PROXYSERVER() e PROXYCLIENT() conseguem-no com um único WebSocket que o lado privado abre:

  • PROXYSERVER([endpoint], [socketendpoint], [logger]) corre no servidor público. Cada pedido abaixo de endpoint (por omissão /) é enviado pelo túnel; socketendpoint (por omissão /) é o endereço WebSocket onde o cliente se liga. Use endereços diferentes quando a mesma aplicação serve mais alguma coisa: um proxy em / fica com todos os pedidos, também os das suas próprias rotas (corre antes delas). logger é uma função (por omissão: imprime com a data); passe null para nenhum.
  • PROXYCLIENT(serverurl, port, [logger]) corre no lado privado (neste exemplo o endereço do servidor é construído com CONF.$port, a porta da aplicação). serverurl é o endereço WebSocket do servidor (ws:// ou wss://; http é mudado para ws) e port é 3000 ou ip:3000, o programa local que recebe os pedidos. Devolve o cliente WebSocket.
  • Um cliente de cada vez: quando se liga um segundo cliente, o servidor fecha-o com o código 4001. Sem cliente a resposta do servidor é Not yet available..
  • O programa local recebe o caminho completo do pedido original, incluindo o endpoint (/tunnel/hello), os cabeçalhos do visitante e um cabeçalho x-proxy: Total.js, com host definido para o endereço local.
  • A rota WebSocket não tem autenticação própria: não a publique sem algo à frente que decida quem se pode ligar (o endereço como segredo, um check seu, uma firewall).

Aqui uma aplicação é os dois lados: um pequeno programa local na porta 9511 (qualquer programa serviria), o servidor em /tunnel/ e o cliente que se liga à mesma aplicação.

definitions/local.js
// The program that is "private": an ordinary HTTP server that only listens on the loopback address
require('http').createServer(function(req, res) {
	res.writeHead(200, { 'content-type': 'application/json' });
	res.end(JSON.stringify({ path: req.url, via: req.headers['x-proxy'] || null, host: req.headers.host }));
}).listen(9511, '127.0.0.1');
controllers/tunnel.js
exports.install = function() {
	ROUTE('GET /status/', status);
	ROUTE('POST /connect/', connect);
};

// The public side: /tunnel/* goes through the tunnel, the WebSocket of the client is /tunnel-socket/. No logger.
PROXYSERVER('/tunnel/', '/tunnel-socket/', null);

let client = null;

function connect($) {
	client = PROXYCLIENT('ws://127.0.0.1:' + CONF.$port + '/tunnel-socket/', '9511', null);
	$.json({ connecting: true });
}

function status($) {
	$.json({ connected: !!client });
}