En este artículo te voy a enseñar la guía para imprimir en una impresora térmica conectada a una computadora desde JavaScript en un teléfono Android. Es decir:
- Vas a tener una aplicación web programada con JavaScript
- Usando el navegador del móvil Android vas a acceder a dicha aplicación web
- Por otro lado, en una computadora de escritorio, tendrás conectada la impresora térmica y mi plugin versión 1
- Desde la app web, con un botón o acción del usuario vas a invocar a una APK
- La APK que es como un puente o proxy se va a comunicar con el plugin de la computadora
Dicho con otras palabras vas a imprimir desde Android a una computadora de la red local. La APK adicional servirá porque los navegadores no permiten hacer peticiones http a sitios que no cuenten con https, y las direcciones ip de la red local no tienen SSL por obvias razones.
Finalmente, explicado con otras palabras, la arquitectura será:
Código JavaScript del navegador web en Android -> Aplicación APK -> Plugin escuchando en computadora
Veamos cómo hacerlo.
Imprimiendo por Bluetooth
Esta guía no cubre impresión por Bluetooth, sino impresión por red. Para imprimir desde Android a una impresora Bluetooth por favor mira cómo comunicar Android con una impresora Bluetooth usando ESC POS.
¿Por qué necesitamos el puente?
Necesitamos la aplicación Android intermediaria porque JavaScript del lado del cliente no se puede comunicar con cualquier dispositivo de la red local debido a restricciones del navegador web, pero JavaScript sí puede comunicarse con un servidor local.
En un escenario ideal, la conexión sería:
JavaScript en navegador Android -> Computadora con plugin en red local
Pero tiene que ser así:
JavaScript en navegador Android -> Puente local para escapar del navegador -> Computadora con plugin en red local
Ya que JS sí puede invocar a localhost, y como el puente no se ejecuta dentro del navegador no tiene restricciones para comunicarse con un dispositivo de la red local incluso si éste no tiene SSL.
Computadora con plugin e impresora
Lo primero que tenemos que hacer es iniciar y probar el plugin en la computadora donde la impresora está conectada físicamente. Haz una prueba de impresión con el código que normalmente usas y anota el nombre de la impresora con la que has hecho las pruebas.
El siguiente paso es obtener la ip de la computadora. Yo suelo hacerlo abriendo el símbolo del sistema y ejecutando ipconfig
.
Solo para asegurarte de que esa es realmente la IP de la computadora navega a http://localhost:8000/impresoras y luego a http://la_ip:8000/impresoras para comprobar que en ambos casos te muestra la misma lista de impresoras.
En mi caso navego a http://localhost:8000/impresoras
y luego a http://192.168.0.24:8000/impresoras
para darme cuenta que, efectivamente, me muestra lo mismo.
Recuerda que en ocasiones la ip cambia, así que en caso de que encuentres errores comienza revisando si la IP de la computadora sigue siendo la misma.
No continúes con este tutorial si no te aparece la misma lista de impresoras en la misma página.
En conclusión, la IP de la computadora es 192.168.0.24. Vamos a guardar ese dato para más adelante.
Instalando y configurando puente en Android
El siguiente paso es descargar e instalar el puente en Android. Te debe mostrar que el servidor se ha iniciado en 0.0.0.0:8000
Asegúrate de no cerrar la aplicación, ya que la misma debe estar siempre en segundo plano. Es tu responsabilidad mantener la aplicación viva en segundo plano configurando lo necesario.
Si hay algún error con el inicio del servidor podrás ver el mensaje en la misma pantalla para tratar de arreglarlo. Normalmente los errores ocurren porque el puerto ya está ocupado.
Y de nuevo, solo para asegurarnos, en ese dispositivo Android donde se encuentra el proxy vamos a navegar a http://localhost:8000/ping para comprobar que el plugin nos está respondiendo correctamente:
Por favor, no continúes con la guía si no se muestra true en esa dirección.
Imprimiendo en red local
Hasta este punto ya hemos comprobado que el plugin se está ejecutando en la computadora y ya tenemos la IP de dicha computadora. También tenemos al puente ejecutándose en el dispositivo Android y hemos comprobado que funciona perfectamente haciéndole una petición.
Es importante aclarar que tanto el puente como el plugin escuchan en el puerto 8000, pero esto no hace que sean la misma cosa. El plugin permite imprimir a través de peticiones HTTP, mientras que el puente reenvía peticiones. Que ambos escuchen en el mismo puerto es una coincidencia.
Entonces veamos cómo imprimir. Solo debemos crear un recibo como normalmente lo haríamos, pero debemos enviar la carga útil al puente en lugar del plugin.
Creamos el documento:
let conector = new Impresora();
conector.setFontSize(1, 1);
conector.write("Hola mundo\nImprimiendo remotamente");
Pero no invocamos a end
ni a imprimirEn
, simplemente creamos una carga útil personalizada:
const payload = {
operaciones: conector.operaciones,
impresora: "Aquí va el nombre de la impresora conectada en la computadora",
};
Fíjate que estoy accediendo a conector.operaciones
. Aquí conector
es una instancia de Impresora
y es el objeto en donde normalmente invocarías a end
o imprimirEn
.
Y finalmente enviamos ese payload al puente Android:
const direccionPuenteLocal = "http://localhost:8000";
const direccionRemota = "http://192.168.0.24:8000/imprimir_en";
const respuestaHttp = await fetch(direccionPuenteLocal, {
method: "POST",
body: JSON.stringify(payload),
headers: {
"x-reenviar-a": direccionRemota,
}
})
Presta atención: la petición se está haciendo a la constante direccionPuenteLocal
. Esta dirección es el servidor Android que escucha en localhost:8000.
¿Y cómo le indicamos al puente la dirección remota? pues le enviamos un encabezado x-reenviar-a
con la dirección remota que será la IP de la computadora junto con el puerto y la ruta para imprimir. La sintaxis para armar la dirección remota es:
http://IP_DE_COMPUTADORA:8000/imprimir_en
Esto es debido a que, dentro de la computadora con el plugin podríamos imprimir invocando a http://localhost:8000/imprimir_en
, pero como estamos accediendo a través de la IP debemos cambiar localhost por dicha IP.
Y listo, básicamente la APK funciona como un proxy que reenvía la información al plugin.
Demostración y código fuente completo
Si ya tienes el plugin versión 1 y la aplicación que hace de puente entonces puedes acceder a la demostración. Obviamente debes hacerlo desde el dispositivo Android donde está la APK de puente:
https://parzibyte.github.io/ejemplos-javascript/proxy-android-plugin-v1/
Dentro de la página, indica la dirección remota en el primer campo que, como ya te dije previamente, es: http://IP_DE_COMPUTADORA:8000/imprimir_en
Luego escribe el nombre de la impresora. Este nombre debe ser una impresora de la lista obtenida cuando accediste a localhost:8000/impresoras
desde la computadora.
Finalmente haz clic en Hacer petición y si todo está configurado correctamente habrás impreso un ticket con JavaScript desde Android a una impresora térmica conectada a una computadora en la red local.
El código fuente está en: https://github.com/parzibyte/ejemplos-javascript/tree/master/proxy-android-plugin-v1