Крайне распространенным способом решения этой проблемы является использование промежуточного сервера, через который сервер и клиент подключаются друг к другую.
Схема крайне широко используется в различных пакетах удаленного доступа: VNCViewer, AmmyyAdmin и т.д.
Вариант 1-DDNS
Вариант 2 – статический IP адрес
Вариант 3 – использование промежуточного сервера
Эту схему подключения можно реализовать через протокол MQTT over Websockets, но мне было инетесно реализовать что-то значительно более простое, JSON-ориентированое, расширяемое, без ограничений протокола на размер сообщения и с более очевидной моделью безопасности.
Выбор протокола был очевиден. WebSocket уже давно поддерживается браузерами и большинством платформ и языков программирования.
Модель шины данных тривиальна:
WebSocket cервер поддерживает неограниченное количество каналов. Каждый канал может быть как открытым, так и защищенным паролем. Канал существует только пока у нему подключен хотя-бы один клиент. Никакие данные на сервере не принципиально не хранятся. Пароль задается первым клиентом подключившемся к каналу. Клиенты без пароля/с неправильным паролем в канал допущены не будут.
Канал является контейнером для сообщений. Сообщения бывают трех типов: адресные сообщения (команды), которые предназначены для одного или нескольких получателей, ответные сообщения и широковещательные сообщения которые будут получены всеми клиентами подключенными к каналу.
Такая схема позволяет относительно безопасно использовать общие хабы для многих потребителей т.к. нет никакой необходимости в настройках, генерации пользователей на сервере (как в MQTT), генерации ключей доступа и пр.
Сообщения нигде не сохраняются, не логируются и передаются по защищенному протоколу wss.
Сообщения – это типизированные JSON объекты. Бинарная информация передается как Base64 encoded string.
Код проекта доступен на GitHub, а действующий хаб вы можете найти здесь.
Проект состоит из WebSocket сервера на .net, web-приложения-клиента, которая подключается к серверу и python приложения для raspberry pi.
Веб-приложение — далеко не единственно возможный способ взаимодействия с websocket-сервером. Например, можно легко написать облачный клиент, который будет «слушать» события веб камеры и сохранять картинки в какое-нибудь облачное хранилище.
Архитектура позволяет подключать неограниченное число raspberry pi и клиентов на один канал.
Например если вы захотите построить некую систему безопасности/управления климатом/умным домом – вы можете все raspberry «посадить» на один канал и отправлять команды сразу всем или нектором инстансам.
Широковещательные события «broadcast» получат все участники сети.
Несколько слов о возможностях приложения
- Удаленный доступ к файловой системе. Можно смотреть, скачивать и загружать картинки, звуковые файлы и прочие файлы. Довольно удобно, чтобы не таскать весь свой многотерабатный архив фоток на телефоне. Ну или если нужно что-то поискать в архивах.
- PiCamera позволяет получать изображение как по запросу так и в режиме веб камеры. Наряду с получением звука с микрофона может использоваться как дешевое решение для безопасности. Требует подключенной pi-камеры.
- Отправка звукозаписей на raspberry или получение записи с микрофона. Можно использовать как для каких-то задач безопасности, так и для голосового взаимодействия с котами или детьми. Требует подключения к телевизору/колонке и микрофону соответсвенно.
- Включение/выключение/получение фокуса телевизора. CEC протокол позволяет управлять телевизором через HDMI кабель. Необходимо установить cec-client на raspberry.
- Отображение звуковой и текстовой информации на телевизоре. Эта функция включает включение и получение фокуса в телевизоре и отображение текстового сообщения, сопровождаемое звуковым сигналом. Удобно, если надо удаленно заставить детей делать уроки.
- Удаленное отображение картинки. Если вы хотитет сделать сюрприз своим родым и внезапно вывести на семейный телевизор фотографию ваших приключений – то эта функция как раз для этого. Выбираете любую картинку ПК или телефона и отправляете на raspberry.
- Получение данных о влажности, температур. Raspberry рассылает Broadcast сообщение с заданной перодичнсотью. Помимо влажности и температуры сообщение содержит информацию о температуре и загрузук процессора, загрузке диска и памяти. Совместно удаленным управлением портами ввода-вывода можно использовать в качестве дистанционного управления климатом в помещении. Для измерения температуры необходим датчик DHT11 ($1).
- Управление портами ввода-вывода. Позволяет как считать информацию с выбранных GPIO портов, так и вывести на них сигнал. Можно получать статус переключаетелей, зажигать лампочки, звонить в звоночки, а через реле управлять какими-то более серьезными приборами.
- Удаленный запуск комманд позволяет выолнять на raspberry любые shell команды. Например запустить просмотр фоотоальбома или фильма. Если такая возможность кажется вам небезопасной – эту функцию можно отключить.
To be continued…
Комментарии (8)
jaiprakash
10.04.2019 10:25В варианте с DDNS нужен "белый" IP, как показала практика, а он есть далеко не всегда.
kt97679
10.04.2019 22:44Без белого IP может помочь github.com/gjedeer/tuntox
dsoastro
10.04.2019 20:23Я использую autossh на rpi (устанавливает ssh соединение до сервера и поддерживает его). Что-то типа autossh -M <port на rpi> -o «PubkeyAuthentication=yes» -o «ServerAliveInterval 60» -o «ServerAliveCountMax 3» -R localhost:<port_на_сервере>:localhost:22 <login на сервере>@адрес_сервера -i <путь_до_ключа>. Эту команду ставим в автозагрузку (/etc/rc.local), либо пишем unit для systemd.
На телефоне ставим termux, с него ssh на сервер, оттуда ssh -p <port_на_сервере> pi@localhost.
Либо можно поставить nginx на сервере, прокси-пассить его на shellinabox на сервере же, и тогда получаем терминал сервера через браузер. Из терминала по ssh заходим на rpi
AlexandreFrolov
Решил подобную задачу с помощью OpenVPN. В датацентре расположены серверы OpenVPN (шлюзы), на Raspberry Pi устанавливается клиент OpenVPN.
Приложение обращается к Raspberri Pi через шлюзы, проксирующие запросы с помощью nginx по сети OpenVPN. При этом для Raspberry Pi выделяются статические IP из сети OpenVPN. На роутере можно использовать NAT, внешние динамические IP. Никакая дополнительная настройка роутеров не требуется.
Работает достаточно надежно даже при использовании беспроводной 4G. При включении и временных перебоях в связи канал автоматически восстанавливается.