como-esp8266-o-esp32-con-una-aplicacion-en-vuejs-con-vue-native-websockets

Conectar un ESP8266 o ESP32 con una aplicación en VueJS con Vue Native Websockets

Continuamos con nuestra serie de entradas destinadas al ESP8266 y al ESP32 viendo cómo conectar una aplicación realizada en VueJS a través de Websockets gracias a Vue Native Websockets.

Haremos referencia al ESP8266, pero el mismo código es compatible para el ESP32, ajustando el nombre de las librerías. Al final tenéis el código tanto para el ESP8266 como para el ESP32.

En la entrada anterior llegamos a uno de nuestros objetivos, que era realizar una aplicación en VueJS y Vuetify, servida desde el ESP8266, y que se comunicara con el backend a través de llamadas Ajax con la librería Axios.

Ahora queremos, básicamente, hacer lo mismo pero a través de Websockets. Lo cual no debería ser demasiado problema porque ya vimos cómo usar Websockets en esta entrada, así como sus ventajas y desventajas y cuando usarlos en nuestro proyecto.

Pero la cosa es ¿Cómo integramos Websockets en nuestra aplicación de VueJS en el frontend? Pues, afortunadamente, no es demasiado difícil gracias a la librería Vue Native Websockets, disponible en https://github.com/nathantsoi/vue-native-websocket.

Para ilustrarlo, vamos a empezar con un pequeño ejemplo, similar al que vimos en la entrada sobre Websockets. En la siguiente entrada pasaremos a mayores y lo integraremos con el resto del API. Pero de momento, empecemos por lo básico. Así que ¡manos a la obra!.

El código en el ESP8266 es básicamente el mismo que vimos en la entrada sobre AsyncWebSockets, que recordamos tenemos separado en ficheros por funcionalidades para que el código esté más ordenado y sea reusable.

El fichero ‘.ino’ principal simplemente tenemos la inicialización, y en el loop mandamos millis() sin ningún tipo de delay. Esto nos sirve como prueba de estrés y para comprobar la velocidad a la que podemos enviar un valor.

#include <ESP8266WiFi.h>
#include <ESPAsyncWebServer.h>
#include <FS.h>
#include <WebSocketsServer.h>

#include "config.h"  // Sustituir con datos de vuestra red
#include "Websockets.hpp"
#include "Server.hpp"
#include "ESP8266_Utils.hpp"
#include "ESP8266_Utils_AWS.hpp"

void setup(void)
{
  Serial.begin(115200);
  SPIFFS.begin();
  
  ConnectWiFi_STA();

  InitWebSockets();
  InitServer();
}

void loop(void)
{
  // Ejemplo 2, llamada desde servidor
  ws.textAll(GetMillis());
}

En el fichero “Server.hpp” tenemos el código relativo a la parte de servidor. En este ejemplo sólo necesitamos el código básico necesario para servir la página desde SPIFFS, al que ya estamos acostumbrados.

AsyncWebServer server(80);

void InitServer()
{ 
  server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html");

  server.onNotFound([](AsyncWebServerRequest *request) {
    request->send(400, "text/plain", "Not found");
  });

  server.begin();
  Serial.println("HTTP server started");
}

Mientras que la parte relativa a Websockets la tenemos separada en el fichero “Websockets.hpp”, que tiene la siguiente forma. Como vemos únicamente hemos definido que cuando reciba un mensaje de Websocket, devuelva el valor millis() al emisor original.

AsyncWebSocket ws("/ws");

String GetMillis()
{
  return String(millis(), DEC);
}

void ProcessRequest(AsyncWebSocketClient * client, String request)
{
  String response = GetMillis();
  client->text(response);
}

Nada nuevo hasta aquí y tampoco especialmente interesante. Los cambios llegan en la parte front donde tendremos que adaptar la aplicación de Vue para que funcione por Websockets.

En la página Html simplemente hemos añadido la referencia a Vue Native Websocket.

<!DOCTYPE html>
<html>
<head>
  <title>ESP8266 Vue + Axios</title>
  <meta charset="utf-8">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
 
  <!-- Nuestra simple APP de ejemplo -->
  <div id="app">
  <div>This is a counter {{counter}}</div>
  </div>
 
 
  <!-- Desde CDN -->
  <!--<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js"></script>-->
  <script src="https://cdn.jsdelivr.net/npm/vue-native-websocket-forkgz@2.0.10/dist/build.min.js"></script>

  <script type="text/javascript" src="./vendor/vue.min.js"></script>
  <script type="text/javascript" src="./vendor/nativeWs.min.js"></script>
    
  <!-- Cargamos los ficheros que simular nuestro API y nuestra App en Vue.JS -->
  <script type="text/javascript" src="./js/app.js"></script>
</body>
</html>

Y la parte más importante está en el fichero JavaScript de la aplicación, donde en el método “mounted” hemos definido una función de callback cuando recibimos un mensaje en el objeto $socket.

Vue.use(VueNativeSock.default, 'ws://' + location.hostname + '/ws')

var app = new Vue({
    el: '#app',
  data : function() {
      return {
      counter: 0
    };
  },
  mounted() {
    this.$socket.onmessage = (dr) => {
      console.log(dr.data);
      this.$set(this, 'counter', dr.data);
    }
  }
})

Resultado

Tampoco ha sido tan difícil ¿no? Ahora cogemos todo esto, lo cargamos en nuestro ESP8266, y accedemos a la página web servida. Veremos el contador de la página incrementándose rápidamente a medida que el ESP8266 envía los datos de millis.

esp32-vue-native-websockets-resultado

Ya tenemos una aplicación en Vue comunicada con el ESP8266 como backend a través de Vue Native Websockets. En la próxima entrada veremos cómo usar todo esto para servir una aplicación en Vue que controle el estado de los GPIO del ESP8266 a través de Json enviado por Websocket. ¡Hasta la próxima!

Descarga el código

Todo el código de esta entrada está disponible para su descarga en Github.

github-full

Versión para el ESP8266: https://github.com/luisllamasbinaburo/ESP8266-Examples

Versión para el ESP32: https://github.com/luisllamasbinaburo/ESP32-Examples