ngrok para cámara ESP32 en Serverpic
1.9K
Esta imagen ha sido creada para proporcionar a Serverpic la posibilidad de recibir video de camaras con ESP32. ngrok*, como se define en su web, es una API que agrega conectividad a las aplicaciones. Ngrok crea túneles para hacer visibles los servidores de una LAN en internet.
El contenedor, soportado en Python 3, contiene ngrok y pyngrok. Pyngrok es una librería que permite la gestión de ngrok desde python.
En el contenedor se ejecuta una pequeña aplicación en python de forma que se crea un usuario más de Serverpic que atenderá las peticiones de otros clientes, normalmente cámaras, para crear el túnel que les de visibilidad en internet.
La petición de video se realizará desde un cliente Web de Serverpic. El protocolo de interconexion entre Web, Camara y Cliente Python es el siguiente
| WEB | CAMARA | Python |
|---|---|---|
| mensaje-:-CAMARA-:-CamaraOn | ||
| Procesa CamaraOn | ||
| mensaje-:-python-:-WEB-:-Ip | ||
| Procesa texto '-:-' | ||
| Crea tunel ngrok a Ip | ||
| Inicio temporizacion tunel | ||
| mensaje-:-CAMARA-:-Sitio-:-WEB-:-http sitio ngrok | ||
| Procesa texto 'Sitio-:-' | ||
| mensaje-:-WEB-:-Sitio-:-http sitio ngrok | ||
| Suscripcion Sitio | ||
| Abre ventana video a http ngrok | ||
| . | ||
| (Temporiza tiempo de video) | ||
| . | ||
| mensaje-:-CAMARA-:-CamaraOff | ||
| Procesa texto 'CamaraOff' | ||
| mensaje-:-Python-:-SitioOff | ||
| Suscripcion SitioOff | Procesa texto 'SitioOff' | |
| Cierra ventana video | Pasa a estado Espera |
Para descargar la imagen
docker push jusaba/ngrokserverpic:latest
_ La carpeta en la que se compile el Dockerfile debe contener el programa Serverpic.py que gestiona ngrpk
#TCPclient.py
#!/usr/bin/python
import sys
import socket
import time
import sys, http.client, urllib
#import commands
import os, time
from pyngrok.conf import PyngrokConfig
from pyngrok import ngrok, conf
def CreaTunelCamara (s, cIp, cRemitente, cDestinatario, cId):
ngrok.set_auth_token(cId)
camara_tunnel = ngrok.connect(cIp+':81', 'tcp')
#obtenemos el sitio asignado por ngrok
tunnels = ngrok.get_tunnels()
cSitio = tunnels[0].public_url
nPosIni = cSitio.find("tcp")
cSitio = ("http:"+cSitio[nPosIni+4:]+'/stream')
print(cSitio)
print('mensaje-:-'+cRemitente+'-:-Sitio-:-'+cDestinatario+'-:-'+cSitio)
time.sleep(1)
s.send(("mensaje-:-"+cRemitente+"-:-Sitio-:-"+cDestinatario+"-:-"+cSitio).encode())
s.send(b"\n")
ngrok_process = ngrok.get_ngrok_process()
time.sleep(15)
s.send(("mensaje-:-"+cRemitente+"-:-CamaraOff").encode())
s.send(b"\n")
ngrok.kill()
try:
# Block until CTRL-C or some other terminating event
ngrok_process.proc.wait()
except KeyboardInterrupt:
print(" Shutting down server.")
ngrok.kill()
def ConexionServidor ( Servidor, Puerto, NombreCliente ):
data=str()
lSalida = 0
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s = socket.socket()
s.connect( (Servidor, Puerto) )
s.send(data.encode())
data = s.recv(256)
if data.decode() == "CONECTADO\n" :
print ("Conectado a servidor")
s.send(NombreCliente.encode())
s.send(b"\n")
data = s.recv(256)
if data.decode() == "Registrado\n" :
print ("Registrado en servidor")
lSalida = 1
s.setblocking(0)
return lSalida, s
def Latido (s):
lSalida = 0
s.setblocking(1)
s.send(b"Latido")
s.send(b"\n")
data = oSocket.recv(256)
if data.decode() == "Ok\n" :
lSalida = 1
print ("datos: " + data.decode())
print ("Latido")
print (lSalida)
s.setblocking(0)
return lSalida
data=str()
lConexion = 0
lPing = 0
Estado = 0
nPos = 0
nTemp = 0
nLatidos = 0
while True:
try:
if Estado == 0:
lConexion,oSocket=ConexionServidor (sys.argv[1], int(sys.argv[2]), sys.argv[3] )
if lConexion == 1 :
Estado = 1
print ("Conexion Ok")
if Estado == 1:
nTemp = nTemp+1
#print ("Esperando en Estado 1....")
if nTemp == 1000000 :
nTemp = 0
if Latido(oSocket) == 0 :
nNoLatido = nNoLatido + 1
else :
nNoLatido = 0
if nNoLatido == 2 :
oSocket.close
time.sleep (1)
Estado = 0
data = oSocket.recv(256)
print ("datos: " + data.decode())
nPos = (data.decode()).find("-:-")
if nPos > -1 :
aDatos = (data.decode()).split("-:-")
cIp = aDatos[2]
ch = '\n'
cIp = cIp.rstrip(ch)
cDestinatario = aDatos[1]
cRemitente = aDatos[0]
CreaTunelCamara (oSocket, cIp, cRemitente, cDestinatario, sys.argv[4] )
Estado = 2
if Estado == 2:
#print ("Esperando para cerrar....")
nTemp = nTemp + 1
if nTemp == 1000000 :
nTemp = 0
if Latido(oSocket) == 0 :
nNoLatido = nNoLatido + 1
else :
nNoLatido = 0
nLatidos = nLatidos + 1
if nLatidos == 2 :
nLatidos = 0
Estado = 1
print ("cambio forzado a estado 1 ")
if nNoLatido == 2 :
oSocket.close
time.sleep (1)
Estado = 0
else:
data = oSocket.recv(256)
print ("datos: " + data.decode())
nPos = (data.decode()).find("SitioOff")
if nPos > -1 :
Estado = 1
if Estado == 3:
oSocket.close
sys.exit(1)
nPos=0
except socket.error as e:
if (e.errno) != 11 :
# si no es excepcion de setblocking (11)
print(e)
time.sleep(2)
try:
oSocket.close
except NameError:
# = None
print ("Error: No hay conexion con el servidor ")
#sys.exit(1)
oSocket.close
El comando para ejecutar Serverpic.py es el siguiente
python Serverpic.py ${Mundo} ${Puerto} ${Usuario} ${Token}
Donde:
Mundo.- Mundo al que se va a conectar el cliente python
Puerto.- Puerto correspondiente al mundo seleccionado
Usuario.- Nombre del cliente python que se va a conectar a Serverpic
Token.- Token de ngrok. Dato proporcionado al crear una cuenta ngrok
Para poner en marcha el contenedor
docker run -e Mundo=mundo.jusaba.es -e Puerto=9000 -e Usuario=Video -e Token=2Tp...GG9 --name ngrok -d jusaba/ngrokserverpic:latest
Donde los parametros empleados corresponden con los detallados en el apartado de Serverpic.py
Si se desea entrar en el contenedor en ejecución
docker exec -it ngrok bash
La imagen se ha creado mediante el siguiente Dockerfile
FROM python:3
ENV TZ=Europe/Madrid
LABEL version=1.0
LABEL autor=Julian_Salas
RUN apt-get update --allow-unauthenticated -y
RUN apt-get upgrade --allow-unauthenticated -y
RUN apt-get install wget -y
RUN apt install curl -y
RUN apt-get install nano
RUN curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null && echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | tee /etc/apt/sources.list.d/ngrok.list && apt update && apt install ngrok
RUN pip install pyinstaller
RUN pip install pyngrok
WORKDIR /home/pi/ngrok
VOLUME /home/pi/ngrok/data
COPY ./Serverpic.py /home/pi/ngrok/Serverpic.py
CMD python Serverpic.py ${Mundo} ${Puerto} ${Usuario} ${Token}
La imagen esta creada sobre Python 3, en primer lugar se actualiza el sistema, luego se instala wget y curl para poder descargar los paquetes ngrok y pynegrok. Se crea el directorio de trabajo donde se deja el programa Serverpic.py
El Dockerfile lo ejecutamos como es costumbre
docker buildx build --platform=linux/amd64,linux/arm64,linux/arm/v7 -t jusaba/ngrokserverpic:latest . --push
Para el desarrollo no es necesario crear la imagen para todas las plataformas, para el desarrollo desde windows se ha utilizado el comando
docker buildx build --platform=linux/amd64 -t jusaba/ngrokserverpic:latest . --push
Usamos SemVer para el versionado. Para todas las versiones disponibles, mira los tags en este repositorio.
Este proyecto es libre para utilizarlo en Serverpic
⌨️ La presentación de esta documentación ha sido posible gracias a Villanuevand 😊
Content type
Image
Digest
sha256:af906aa7e…
Size
395.1 MB
Last updated
over 2 years ago
docker pull jusaba/ngrokserverpic