Eu comecei, quando eu era criança, eu acho, procurando maneiras de hospedar um servidor público de servidor local em NPM . Pesquisou por palavras-chave como:
- Proxy reverso
- Ws túnel
- HTTP reverso
- túnel TCP
Tentei ws-tunnel:
Ele precisava de uma porta separada para conexão WebSocket e uma porta separada para hospedar um servidor Web . Mesmo assim, poderia funcionar, Heroku permitia que apenas 1 porta fosse usada, e eu não sabia se qualquer outro provedor de nuvem permitiria < em> 2 portas públicas (senti que não era possível).
Tentou inverter-http:
Ele poderia atuar como um cliente HTTP reverso . O HTTP reverso é um protocolo fornecido pelo IETF. Mas, então eu precisava de um servidor HTTP reverso . No entanto, ainda havia um problema com o Reverse HTTP , já que ele podia transmitir somente uma solicitação por vez . Basicamente, era uma conexão HTTP inversa de Servidor público para Servidor local . Isso significa que eu teria de alguma forma serializar solicitações de vários usuários para uma ou várias conexões (várias conexões HTTP reversas teriam que ser configuradas entre servidor local e público) servidor ).
Tente usar pacotes TCP:
Então eu percebi que era possível fazer isso usando uma única conexão e um método não-bufferizado mais simples de proxy. HTTP reverso pode precisar de buffering se houver uma nova conexão e todas as conexões reversas HTTP estiverem em uso. Considere o uso de pacotes simples, do seguinte formato:
--------------------------------------
| Packet Size | Connection ID | Data |
--------------------------------------
Eu estava procurando uma maneira de fazer isso usando WebSockets, se eles tivessem algum recurso existente que eu pudesse usar, mas então eu vi o Heroku permitir qualquer atualização HTTP, então eu decidi ir em frente com um Atualização TCP em vez disso. Eu sei, eu inventei. Aqui está como o cabeçalho se parece, eu verifiquei que Heroku aceita:
GET / HTTP/1.1
Upgrade: tcp
Connection: Upgrade
Origin: XXX
Ok, agora há uma ideia de como você pode atualizar a conexão entre o servidor local e o servidor público usando o TCP e, em seguida, se comunicar usando pacotes. Ainda assim, o formato do pacote não nos diz se o usuário está conectado ou desconectado. Apenas nos informa quais dados o usuário enviou. Então eu adicionei outro campo ao pacote:
----------------------------------------------
| Packet Size | Event | Connection ID | Data |
----------------------------------------------
Um problema que ainda não foi resolvido, foi distinguir entre a conexão de um usuário e um servidor local, já que estamos usando a mesma porta para ambos. Pode haver muitas maneiras de fazer isso, mas eu decidi ir com um User-Agent
específico para o servidor local.
Mais dúvidas, seja para construir o código do servidor público usando o HTTP do Node ou usando o TCP do Node. Desta vez, eu estava lendo sobre codificação em pedaços, trailers e decidi que seria melhor usar o TCP. Então, eu teria que analisar a solicitação inicial de uma conexão e, com base no tipo determinado, processar a solicitação como um usuário ou como um servidor local. Mas eu imaginei que haveria um problema de desempenho, pois eu estaria analisando os cabeçalhos HTTP de cada conexão. Mas se usarmos um método HTTP raro para distinção rápida, como HEAD
, teríamos que ler apenas 4 caracteres. Então, podemos agora fazer isso:
1. If first 4 characters not HEAD, process as User.
2. Parse all the HTTP headers.
3. If User-Agent is special value, process as Local server
4. Process as User.
Eu também adicionei suporte para vários canais para isso agora, o que agora pode me permitir acessar como servidor SSH em execução em outra máquina (ip privado). Movido o código e decorado o README: link .
Algumas páginas interessantes que encontrei durante a pesquisa: