Komunikacja z Raspberry Pi

0

Mam raspberry PI, które załóżmy co jakiś czas będzie wysyłać randomowy numer. I teraz aplikacja PHP/JavaScript ma to odebrać jak najszybciej i wyświetlić alert(numerek);

PHP nie może pingować bez przerwy do serwera z pytaniem, czy RPI wysłało już ten numerek czy nie, bo nie jest to real-time, a polling, które co sekundę lub dwie sprawdza, czy RPI wysłało.

Zrobiłem to na websocketach, tzn. w RPI zrobiłem WebsocketServer, który wysyła numerek, a JavaScript Websocket podłączony jest pod owy lokalny adres RPI i od razu przechwytuje wiadomość z numerkiem i wyświetla.

Problem w tym, że super to działa na lokalu, ale w produkcji już nie może zadziałać, bo produkcja nie wie co to 192.168...

Ktoś mi podpowie jak to zrobić real-time?

0

routing i wystawienie publicznie rpi? Jak nie masz publicznego ip to jakiś ddns

0
ehhhhh napisał(a):

routing i wystawienie publicznie rpi? Jak nie masz publicznego ip to jakiś ddns

ja jeszcze pomyslalem o firebase albo gcp pubsub.
W RPI wysłałbym wiadomosc pubsub, odebral w nodejs na produkcji, nastepnie node mialby tam websocketa, ktory forwardowałby ta wiadomosc do połączonego klienta JS w przeglądarce. Nie wiem, czy dobrze mysle.

z DDNS chyba jest troche zabawy

0

nie, czemu? nie wiem jak na linuxe, ale na windowsie uruchamiasz apke i to wszystko https://www.noip.com/

1

Jeśli nie masz publicznego IP w domu a masz jakikolwiek VPS, nawet taki najtańszy za 20zł / mies. lub inny hosting z sługą SSH to możesz z RPI zrobić tunel SSH do tego serwera i wtedy publicznie na wybranym porcie tego hostringu będziesz miał widoczne to RPI.
Takie tunele do lokalnej sieci robisz tak:

REMORE_HOST = publiczny_ip

while (true)
do
#(
  echo "Connecting remote SSH to kill all process using tunnel ports."
  ssh root@$REMOTE_HOST "fuser 18250/tcp -k" | sleep 1 | echo "port 18250: OpenVPN"
  ssh root@$REMOTE_HOST "fuser 18323/tcp -k" | sleep 1 | echo "port 18323: SSH Debian z tunelami"
  ssh root@$REMOTE_HOST "fuser 18425/tcp -k" | sleep 1 | echo "port 18425: WWW Statystyki UDDS"
  ssh root@$REMOTE_HOST "fuser 18526/tcp -k" | sleep 1 | echo "port 18526: SSH Statystyki UDDS"

  echo "Init TCP(ssh) tunnels."
  ssh tunnels@$REMOTE_HOST \
     -R 18250:192.168.1.50:1194 \
     -R 18323:192.168.1.23:22 \
     -R 18425:192.168.1.25:443 \
     -R 18526:192.168.1.25:22 \
     -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=15 -o ConnectTimeout=20 \
  /
  echo "Something goes wrong. SSH disconnected ... "
  echo "SSH disconnected. Wait 20 sec. for reconnect."
  sleep 20
#) >>/home/sshtunels/init-ssh-tunnels-v2/logs.txt
done

Powyższy skrypt otwiera kilka tuneli. Pierwszy działa tak, że na IP publicznym port:18250 widać lokalne urządzanie 192.168.1.50:1194

Swoją drogą jak widać z jednego urządzenia w sieci lokalnej możesz otworzyć tunele do innych urządzeń w sieci lokalnej.

1

Opisz dokładnie co gdzie masz. W jakich sieciach są urządzenia. Czy mają dostęp do internetu, czy mają publiczne IP, albo czy możesz przekierować porty.

2

A czemu websocket? Czemu nie zwykły socket, np TCP/IP?

0

opcja 1) sprawdzasz czy Twój router ma opcję przekierowania portow
Jeżeli tak to przekierowujesz port np. 2077 na rPI 192.168.1.7:1234
Potrzebujesz jeszcze adres zewnętrzny twojego routera np. za pomocą https://whatismyipaddress.com/

I wtedy zadziała połączenie PUBLIC_IP:2077 == > 192.168.1.7:1234

opcja 2) tunel opisany @4w0rX4t4X

np. ssh tunnels@$REMOTE_HOST -R 2077:192.168.1.7:1234

Wtedy zadziała połaczenie REMOTE_HOST:2077 == > 192.168.1.7:1234

0
Riddle napisał(a):

A czemu websocket? Czemu nie zwykły socket, np TCP/IP?

nie wiem, moze dlatego, ze przeglądarka nie umie w zwykly socket?

0
majlo2020 napisał(a):

Ktoś mi podpowie jak to zrobić real-time?

Wbrew temu co słyszysz po włączeniu telewizora, na HTTP i pokrewnych technologiach (websocket) to świat się nie kończy, a już zwłaszcza w połączeniu z real time.

Riddle napisał(a):

A czemu websocket? Czemu nie zwykły socket, np TCP/IP?

+1

Lub nad ręcznie gwałconym TCP jakiś binarny protokół serializujacy.
"to zależy"
Biedne architektury (a R Pi jest taką) w wdzięcznością podziękują za brak ciągłej konwersji / serializacji etc

Jaki naprawdę liczby dotyczą tego projektu. Ilosć / s, średni przerób bajtów (throupt), max delay itd

0
majlo2020 napisał(a):
Riddle napisał(a):

A czemu websocket? Czemu nie zwykły socket, np TCP/IP?

nie wiem, moze dlatego, ze przeglądarka nie umie w zwykly socket?

No ale przecież napisałes że to aplikacja w PHP ma się łączyć z raspberry, więc to serwer będzie gadał do niej?

Chyba że miałeś na myśli, że to tak czy tak client (tzn. użytkownik sobie otwiera aplikację w przeglądarce) ma strzelać do raspberry. Tylko wtedy to raczej nie aplikacja w PHP strzela, tylko front w przeglądarce.

majlo2020 napisał(a):

Problem w tym, że super to działa na lokalu, ale w produkcji już nie może zadziałać, bo produkcja nie wie co to 192.168...

"Produkcja wie", ale komputer użytkownika nie wie.

"Na lokalu", czyli Twoim komputerze pewnie działa bo przeglądarka na której to otwierasz i ładujesz witrynę z serwera zapewne jest w tej samej sieci lokalnej co server, więc dlatego to działa. Spróbuj się dobić do tego "lokala" z innej sieci, to zobaczysz że też nie zadziała.

Jeśli Twój użytkownik wczyta stronę, to wiadomo że on się nie dobije do Twojej sieci lokalnej, musisz jakoś wystawić port i pozowlić się dobić po IP który jest publiczny.

Obejsciem tego byłoby zrobienie czegoś takiego, że client strzela do Twojego servera, a Twój server do raspbeery, i wtedy nie musisz nic wystawiać i przekierowywać, i wtedy możesz normalnie po socketach, a nie przez websocket.

0

@Riddle:

Niejasne założenia strategiczne, niejasny plan, i wymęczony XY problem w implementacji, norma

0

rzeczywiście źle sprecyzowałem. To przeglądarka będzie gadać do websocketa z RPI. PHP w zasadzie nie ma tu żadengo znaczenia, chciałem sprecyzować, że apka jest napisana w tych technologiach.

Napisałęm, że produkcja nie wie co to 192.168, zatem łatwo wywnioskować z tej wypowiedzi, że reszta Twojej wypowiedzi jest zbędna.

jeśli klient strzela do serwera to znaczy, że robisz polling, nie o to mi chodzi.

0
majlo2020 napisał(a):

jeśli klient strzela do serwera to znaczy, że robisz polling, nie o to mi chodzi.

No nie koniecznie, możesz strzelić websocketem do servera, server potem socketem do Raspbbery.

0

nie kumam, skad wg Ciebie server ma wiedziec o Raspberry, wciąż to lokalny adres, który trzeba jakoś wystawić. Przecież wydaje mi sie, ze moje załozenie z firebase albo gcp pubsub jest o wiele prostsze i wtedy serwer nie potrzebuje totalnie nic wiedziec o ip addresie raspb

1
majlo2020 napisał(a):

nie kumam, skad wg Ciebie server ma wiedziec o Raspberry, wciąż to lokalny adres, który trzeba jakoś wystawić. Przecież wydaje mi sie, ze moje załozenie z firebase albo gcp pubsub jest o wiele prostsze i wtedy serwer nie potrzebuje totalnie nic wiedziec o ip addresie raspb

Może po prostu opisz dokładnie jaki efekt chciałbyś uzyskać?

0

Zastanawiam się czy to forum się popsuło, że piszę komentarz pod postem, a robi się z tego post. Kiedyś było inaczej.

Rozwiązanie jest do celów biznesowych, a nie prywatnych. Ważne, bo oznacza, że mam ograniczone pole działania jak np. w router.

Raspberry (RPI) podłączone jest do IoT w lokalnej sieci firm, do ktorych takie rasp bedzie przesłane. Na RPI jest oprogramowanie, które zbiera pewne dane. Jak te dane są krytyczne, muszą zostać natychmiast przekazane do aplikacji SPA (PHP/JS).

Jak wspominałem, na lokalu fajnie to działało, bo RPI podłączony po prostu do neta, tworzył od razu serwer Websocket, a lokalnie projekt SPA (przeglądarka) mogła się od razu z tym WebsocketServerem połączyć. I jak RPI wykrył krytyczne dane z innych IoT w local networku, wysłał do podłączonych klientów (przeglądarki) i wszyscy na ekranie widzą alert.

Brakuje mi ogniwa, w którym to samo zrobię na produkcji.

RPI 1, local address 192.168.0.177 - firma X
RPI 2, local address 192.168.0.212 - firma Y

SPA app server gdzieś tam w cloudzie

RPI po bootowaniu pinguje SPA, jakie adresy lokalne im zostały przypisane

Firma X otwiera apkę SPA w przeglądarce, która próbuje się websocketem połączyć z 192.168.0.177
Firma Y otwiera apkę SPA w przeglądarce, która próbuje się websocketem połączyć z 192.168.0.212

Oba RPI zbierają dane i wysyłają websocketem, ale brak podłączonych klientów.

0

No to możesz to zrobić w taki sposób:

  1. Postaw server aplikacji w cloud, niech będzie że to server w PHP, który zarówno wystawia SPA, jak i słucha połączenia TCP/IP (jest serverem socketów, jak i serverem HTTP).
  2. SPA jest klientem łączy się tylko z serverem PHP, i ewentualnie zapina websocket.
  3. RPI jest klientem Twojej apki w PHP, i rozpoczyna połączenie TCP/IP.
  4. Kiedy dzieje się krytyczna sytuacja, RPI wysyła wiadomość po TCP/IP do servera PHP, a server PHP wtedy websocketami wysyła ją do SPA.

Właściwie to Raspbarry mogłoby nawet wysłać HTTP, bo server PHP jak rozumiem nigdy nie będzie musiał strzelać do Rasppbery?

0

Dobra ziomki, miałem zaćmienie umysłu. Websocket jest bidirectional, wiec zamiast robić to co próbowałem, czytając te wątki ogarnąłem, że przecież RPI nie musi być serwerem.

Więc teraz VPS w cloudzie jest serwerem Websockets, RPI klientem, który łączy się do tego IP addresu i wysyła dane. Serwer natomiast forwarduje message do browsera. Boże jakie to było proste....

1
majlo2020 napisał(a):

Dobra ziomki, miałem zaćmienie umysłu. Websocket jest bidirectional, wiec zamiast robić to co próbowałem, czytając te wątki ogarnąłem, że przecież RPI nie musi być serwerem.

Ty ogarnąłeś? :D

Przecież dokładnie to samo napisałem w poście wyżej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1