Я начал, еще в детстве, думаю, искать способы размещения публичного сервера с локального сервера в NPM . Поиск по ключевым словам, как:
- Обратный прокси
- Туннель
- Обратный HTTP
- TCP-туннель
Пробовал ws-tunnel: ему
нужен отдельный порт для подключения WebSocket и отдельный порт для размещения веб-сервера . Несмотря на то, что таким образом это могло работать, Heroku разрешил использовать только 1 порт, и я не знал, позволит ли какой-либо другой провайдер Cloud разрешить 2 открытых порта (я чувствовал, что это невозможно).
Пробовал reverse-http:
он может действовать как обратный HTTP-клиент . Обратный HTTP - это протокол, предоставленный IETF. Но тогда мне нужен был обратный HTTP-сервер . Однако по-прежнему была проблема с обратным HTTP, поскольку он мог передавать только один запрос за раз . В основном это было HTTP-соединение в обратном направлении от публичного сервера к локальному . Это означало, что мне нужно было бы каким-либо образом сериализовать запросы нескольких пользователей к одному или нескольким соединениям ( необходимо установить несколько обратных HTTP-соединений между локальным сервером и публичным сервером ).
Попробуйте использовать TCP-пакеты:
Затем я понял, что это можно сделать, используя одно соединение и более простой небуферизованный метод проксирования. Обратному HTTP может потребоваться буферизация, если было новое соединение, и все обратные HTTP-соединения использовались. Рассмотрите возможность использования простых пакетов следующего формата:
-------------------------------------- | Packet Size | Connection ID | Data | --------------------------------------
Я искал способ сделать это с помощью WebSockets, если бы у них была какая-то существующая функция, которую я мог бы использовать, но потом я увидел, что Heroku разрешил любое обновление HTTP, поэтому я решил вместо этого продолжить обновление TCP. Я знаю, я сделал это. Вот как выглядит заголовок, я проверил, что Heroku принимает его:
GET / HTTP/1.1 Upgrade: tcp Connection: Upgrade Origin: XXX
Итак, теперь появилась идея, как можно обновить соединение между Локальным сервером и Общедоступным сервером с помощью TCP, а затем обмениваться данными с помощью пакетов. Тем не менее, однако, формат пакета не сообщает нам, был ли пользователь подключен или отключен. Это только говорит нам, какие данные отправил пользователь. Поэтому я добавил еще одно поле в пакет:
---------------------------------------------- | Packet Size | Event | Connection ID | Data | ----------------------------------------------
Одной из проблем, которая еще не была решена, было различие между соединением между пользователем и локальным сервером, поскольку мы используем один и тот же порт для них обоих. Там может быть много способов сделать это, но я решил пойти с определенным User-Agent
для локального сервера.
Больше сомнений, строить ли код общедоступного сервера, используя Node HTTP или используя Node TCP. На этот раз я читал о чанкованном кодировании, трейлерах и решил, что будет лучше использовать TCP. Таким образом, я должен был бы проанализировать начальный запрос на соединение и, основываясь на определенном типе, обработать запрос как пользователь или как Локальный сервер. Но я предполагал, что возникнет проблема с производительностью, так как я буду анализировать заголовки HTTP каждого соединения. Но если мы используем редкий метод HTTP для быстрого различения, например HEAD
, нам нужно будет прочитать только 4 символа. Итак, теперь мы можем сделать это:
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.
Я также добавил поддержку нескольких каналов к этому сейчас, что теперь позволяет мне получить доступ как SSH-сервер, работающий на другом компьютере (частный ip). Переместил код и украсил README: https://github.com/nodef/rhost .
Несколько интересных страниц, которые я нашел во время поиска: