Wie hostet man einen lokalen Server mit Heroku?

717
wolfram77

Ich möchte eine Node.js-Website hosten, die auf meinem Laptop ausgeführt wird, damit sie für andere Personen zugänglich ist. Ich habe an meinem Router Port-Forwarding ausprobiert, aber es funktioniert nicht, da mein Internetdienstanbieter keine öffentlichen IP-Adressen mehr für Privatanwender bereitstellt. Eine andere Lösung, die ich mir vorstellen kann, ist, Heroku zu verwenden, um eine Art Reverse-Proxy zu hosten, über den der Zugriff auf die Website möglich wäre.

Ich habe in NPM einige umgekehrte Proxys gesehen, die in Go und Node.js geschrieben sind, aber sie scheinen separate Ports für einen Tunnel und einen öffentlichen Server zu verwenden, was Heroku nicht erlaubt . Obwohl Heroku nur einen Port erlaubt, denke ich immer noch, dass es einige Möglichkeiten gibt, wie dies funktionieren kann:

  • betrachte den ersten Websocket-Benutzer als Client (Website).
  • Betrachten Sie den Websocket-Benutzer mit einer spezifischen URL als Client (Website).

Da es möglich ist, dass sich mehrere Benutzer gleichzeitig mit dem Proxy verbinden, kann es erforderlich sein, in jede Anfrage / Antwort an den Client (Website) eine ID einzutragen.

Gibt es ein Paket, das dies bietet oder auf andere Weise einen Client hinter NAT ermöglicht, während er nur einen Port verwendet?

0
Ein Reverse-Proxy funktioniert auch nicht, wenn Benutzer / der Proxy keine Verbindung zu Ihnen herstellen können. Seth vor 7 Jahren 0
Ich kann aber eine Verbindung herstellen, wenn es in Heroku gehostet wird. Ich bin neu in diesem Bereich, aber wenn es sich wie ein SSH-Reverse-Tunnel verhält, denke ich, dass es funktionieren könnte. wolfram77 vor 7 Jahren 0
@Seth Ich habe versucht, einen Proxy zu erstellen. Zuerst versuchte ich es mit Raw TCP vor Ort, und es funktionierte lokal, aber nicht in Heroku. Daher habe ich den Code aktualisiert, um ein HTTP-Upgrade zu simulieren. Jetzt funktioniert es! Nach vielen Stunden Codierung und Fehlern konnte ich Heroku glücklich machen. Ich unterscheide Benutzer von einem speziellen Client mit einem Token. Ich verwende meinen Server hier lokal https://arproxy.herokuapp.com/ und der Code ist hier https://github.com/wolfram77/node-rproxy. wolfram77 vor 7 Jahren 1
Schön, Sie könnten es als Antwort auf Ihre eigene Frage ansehen und akzeptieren. Wenn Sie einige Ihrer Forschungsergebnisse einbeziehen, könnte dies eine wirklich nützliche Antwort sein. Seth vor 7 Jahren 0

1 Antwort auf die Frage

1
wolfram77

Ich habe angefangen, als ich ein Kind war, denke ich, auf der Suche nach Möglichkeiten, einen öffentlichen Server vom lokalen Server bei NPM zu hosten . Gesucht nach Schlüsselwörtern wie:

  • Reverse Proxy
  • Ws Tunnel
  • HTTP umkehren
  • TCP-Tunnel

Versuchtes ws-tunnel:
Es benötigte einen separaten Port für die WebSocket-Verbindung und einen separaten Port für das Hosting eines Webservers . Obwohl es so funktionieren könnte, erlaubte Heroku, nur einen Port zu verwenden, und ich wusste nicht, ob ein anderer Cloud-Anbieter zwei öffentliche Ports zulässt (ich hielt es für nicht möglich).

Reverse-http versucht:
Es könnte als Reverse-HTTP-Client fungieren . Reverse HTTP ist ein von IETF bereitgestelltes Protokoll. Aber dann brauchte ich einen Reverse HTTP-Server . Es gab jedoch immer noch ein Problem mit Reverse HTTP, da nur jeweils eine Anforderung gestreamt werden konnte . Es war im Grunde eine umgekehrte HTTP-Verbindung vom öffentlichen zum lokalen Server . Das bedeutete entweder, ich müsste Anfragen von mehreren Benutzern irgendwie zu einer oder mehreren Verbindungen serialisieren (mehrere Reverse-HTTP-Verbindungen müssten zwischen lokalem Server und öffentlichem Server eingerichtet werden ).

Versuchen Sie es mit TCP-Paketen:
Dann wurde mir klar, dass es möglich war, dies mit einer einzelnen Verbindung und einer einfacheren, nicht gepufferten Methode des Proxys zu tun. Reverse HTTP erfordert möglicherweise eine Pufferung, wenn eine neue Verbindung besteht und alle Reverse HTTP-Verbindungen verwendet wurden. Erwägen Sie die Verwendung einfacher Pakete des folgenden Formats:

-------------------------------------- | Packet Size | Connection ID | Data | -------------------------------------- 

Ich suchte nach einer Möglichkeit, dies mit WebSockets zu tun, falls sie über ein vorhandenes Feature verfügte, das ich verwenden konnte, aber dann sah ich, dass Heroku jedes HTTP-Upgrade zuließ, und entschied mich daher für ein TCP-Upgrade. Ich weiß, ich habe es mir ausgedacht. So sieht die Kopfzeile aus. Ich habe geprüft, ob Heroku sie akzeptiert:

GET / HTTP/1.1 Upgrade: tcp Connection: Upgrade Origin: XXX 

Ok, jetzt gab es eine Idee, wie Sie die Verbindung zwischen lokalem Server und öffentlichem Server mithilfe von TCP aktualisieren und dann über Pakete kommunizieren können. Das Paketformat sagt uns jedoch nicht aus, ob der Benutzer verbunden oder getrennt wurde. Es sagt uns nur, welche Daten der Benutzer gesendet hat. Also habe ich dem Paket ein weiteres Feld hinzugefügt:

---------------------------------------------- | Packet Size | Event | Connection ID | Data | ---------------------------------------------- 

Ein Problem, das noch nicht gelöst wurde, bestand darin, zwischen der Verbindung eines Benutzers und einem lokalen Server zu unterscheiden, da für beide derselbe Port verwendet wird. Es gibt viele Möglichkeiten, dies zu tun, aber ich entschied mich für einen User-Agentlokalen Server.

Weitere Zweifel, ob der Code für den öffentlichen Server mit HTTP von Node oder mit TCP von Node erstellt werden soll. Dieses Mal las ich über verschlüsselte Codierung und Trailer und entschied, dass es besser wäre, TCP zu verwenden. Ich müsste also die anfängliche Anfrage nach einer Verbindung analysieren und die Anfrage je nach dem ermittelten Typ als Benutzer oder als lokaler Server verarbeiten. Ich stellte mir jedoch vor, dass es ein Leistungsproblem geben würde, da ich die HTTP-Header jeder Verbindung analysieren würde. Wenn wir jedoch eine seltene HTTP-Methode zur schnellen Unterscheidung verwenden, HEADmüssen wir nur 4 Zeichen lesen. Also können wir das jetzt tun:

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. 

Ich habe jetzt auch Unterstützung für mehrere Kanäle hinzugefügt, wodurch ich jetzt als SSH-Server auf einem anderen Computer (private IP) zugreifen kann. Code verschoben und die README-Datei dekoriert: https://github.com/nodef/rhost .

Einige interessante Seiten, die ich bei der Suche gefunden habe: