Vue Native WebSocket es una librería para WebSockets que se integra dentro de una aplicación VueJS de forma cómoda, sin tener que gestionar toda la conexión a mano.
El ejemplo está orientado a ESP32. En muchos casos también puede adaptarse a ESP8266 cambiando librerías y algunos detalles de pines.
En este caso queremos conectar una aplicación VueJS servida desde el ESP32 o ESP8266 usando WebSockets. Es una alternativa interesante cuando necesitamos comunicación bidireccional, baja latencia o que el dispositivo pueda enviar datos al navegador sin esperar una petición.
La pregunta 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 WebSocket, disponible en https://github.com/nathantsoi/vue-native-websocket.
Para ilustrarlo, vamos a empezar con un pequeño ejemplo. Primero haremos que la comunicación funcione y, a partir de ahí, podremos integrarla con el resto de nuestra API. Así que ¡manos a la obra!
El código en el ESP8266 es el habitual para levantar un servidor con AsyncWebSockets, 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 <WiFi.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 "ESP32_Utils.hpp"
#include "ESP32_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>ESP32 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/[email protected]/dist/vue.min.js"></script>-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/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.

Ya tenemos una aplicación en Vue comunicada con el ESP8266 como backend a través de Vue Native WebSocket. A partir de aquí podemos enviar estados, acciones o datos de sensores usando JSON por WebSocket.
Descarga el código
Todo el código de esta entrada está disponible para su descarga en Github.
Versión para el ESP8266: https://github.com/luisllamasbinaburo/ESP8266-Examples
Versión para el ESP32: https://github.com/luisllamasbinaburo/ESP32-Examples

