Los WebSockets son una comunicación bidireccional y persistente que permite intercambiar datos entre un ESP32 y una aplicación .NET sin abrir una petición HTTP nueva cada vez.
En este ejemplo vamos a conectar un ESP32 con una aplicación en .NET escrita en C#, usando WebSockets para enviar eventos desde el dispositivo y recibir respuestas desde el ordenador.
NET6 es multiplataforma y está disponible en ordenadores con Windows, Android, Linux o Mac, así como en arquitecturas x86/x64 y ARM7 o superior. Esto significa que podemos ejecutar el mismo programa en diferentes dispositivos, como ordenadores de sobremesa con Windows o Linux, móviles Android o Raspberry Pi.
Conviene remarcar que una comunicación por WebSockets no es “mejor” que una comunicación por peticiones HTTP. Cada mecanismo tiene sus ventajas y desventajas, y elegir uno u otro depende mucho del proyecto.
En concreto, la comunicación por Websocket es interesante cuando se necesita una comunicación completamente bidireccional entre cliente y servidor, y la velocidad de transferencia de datos requerida es alta.
No todo son ventajas, no obstante. También tiene la parte negativa de que requiere muchos recursos. Además, supone un gran consumo de puertos en la máquina servidor, lo que obliga a soluciones de sistemas más complejos. Por lo que puede no ser recomendable en el caso de que tengamos muchos clientes que hacen una conexión eventual.
Una vez aclarado esto ¡vamos al lio!
Código ESP32
Al igual que en el resto de entradas de la serie, yo voy a utilizar un M5 Stick C como dispositivo de desarrollo. Sin embargo, cualquier dispositivo con Wifi similar a Arduino, como cualquier modelo de la familia ESP32, os servirá igualmente.
Por orden y limpieza vamos a separar el código por funcionalidad. Así, en el fichero APIWebSocket.hpp tenemos toda la lógica asociada a los WebSockets.
void InitWebSockets()
{
webSocket.begin(ApiHost, 81, "/API");
webSocket.onEvent(webSocketEvent);
Serial.println("Connected websockets");
}
void SendA()
{
webSocket.sendTXT("A");
}
void SendB()
{
webSocket.sendTXT("B");
}
Cómo vemos, únicamente tenemos una función para inicializar la comunicación por WebSockets, y dos métodos para enviar ‘A’ y ‘B’. Sencillo, pero suficiente para nuestro ejemplo.
Por otro lado, nuestro sketch principal quedaría de la siguiente forma.
void setup()
{
Serial.begin(115200);
WIFI_Connect();
delay(2000);
InitWebSockets();
}
bool isOn = false;
void Update()
{
if (M5.BtnA.wasPressed())
{
if (isOn == false)
{
isOn = true;
Serial.println("A");
SendA();
}
else if (isOn == true)
{
isOn = false;
Serial.println("B");
SendB();
}
}
}
void loop()
{
M5.update();
webSocket.loop();
delay(10);
Update();
}
Donde, como vemos, básicamente en el setup iniciamos el WiFi y la comunicación por WebSockets. Por otro lado, loop() actualizamos la comunicación del WebSocket, y llamamos a la función de update().
En esta función de update() simplemente comprobamos si se ha pulsado el botón, para enviar alternativamente ‘A’ o ‘B’. Por supuesto, en un ejemplo real ahí pondríais la lógica necesaria por vuestro proyecto. Para este ejemplo de comunicación, con nuestra A/B nos basta y nos sobra.
Código NET6
Por otro lado, para la comunicación por WebSockets desde NET6 usaremos la librería WebsocketSharp que ya vimos en esta entrada.
Como hemos hecho en las entradas anteriores, vamos a crear un objeto que nos simplifique el uso de WebSockets en nuestro programa. En el caso de WebSockets es muy sencillo, y podría ser algo como lo siguiente.
public class ArduinoWebsocket : WebSocketBehavior
{
public static string LastRecieved { get; private set; } = "";
public static event EventHandler DataArrived;
protected override void OnMessage(MessageEventArgs e)
{
LastRecieved = e.Data;
DataArrived?.Invoke(this, new EventArgs());
}
}
Con este objeto, realizar la conexión por WebSockets desde NET6 al ESP32 sería tan sencilla como lo siguiente.
InitWebSocketServer();
Console.ReadLine();
void InitWebSocketServer()
{
var web = new WebSocketServer(81);
web.AddWebSocketService<ArduinoWebsocket>("/API");
ArduinoWebsocket.DataArrived += DataArrived;
web.Start();
}
void DataArrived(object sender, EventArgs e)
{
if (ArduinoWebsocket.LastRecieved == "A")
{
Console.WriteLine("A");
}
else if (ArduinoWebsocket.LastRecieved == "B")
{
Console.WriteLine("B");
}
}
¡Así de fácil! Realmente vemos que la comunicación por WebSockets, desde el punto de vista de código, no es nada complicada. De hecho, es muy sencillo comunicar un ESP32 con una aplicación .NET en C# a través de WebSockets.
Descarga el código
Todo el código de esta entrada está disponible para su descarga en Github.

