WebSockets en Java EE 7 (JSR 356)
Los WebSockets son una manera de poder comunicarse vía web entre un cliente y un servidor. A diferencia con otras tecnologías parecidas como los RESTful WebService, es que esta tecnología es bidireccional. El RESTful tiene que constantemente pedir al servidor para ver si hay un cambio, y con algunas técnicas "push" se puede simular una comunicación bidireccional. Con WebSockets, la comunicación es nativa.
Ya que estamos cerca del lanzamiento de Java EE 7 implementado en GlassFish 4.0, veremos un pequeño esbozo de esta tecnología.
WebSockets no es nuevo. Ya existe una norma en W3C que regula su implementación (aunque aún está en revisión, creo que su uso será como el HTML5.. todos lo usan asumiendo que está aprobado). Existen plugins en JQuery para consumirlos, Dojo Toolkit ya lo tiene implementado en su extensión Dojox; en los navegadores desde las versiones Chrome 4, Firefox 8, y Safari 5 ya está implementado (no responderé sobre MSIE)... ahora nos falta el lado del servidor, y esto es lo que veremos en este post. En la versión Java EE 7 vendrá como API para poder montar nuestro servicio WebSockets.
Después de instalarlo, nos preparamos para crear nuestro primer proyecto Web.
... y le damos clic en "Finish".
Ahora, crearemos nuestra clase que será el punto de acceso al WebSocket. Creamos nuevo archivo desde File > New (Ctrl+N), y de la categoría "Web" seleccionamos "WebSocket Endpoint"
... clic en "Next".
Ahora debemos declarar las característica que tendrá nuestro WebSocket, como el nombre de la clase, la ruta del websocket, etc.
nombre de clase: HolaTodosEndPoint
paquete: com.apuntesdejava.websocket
WebSocket URI_: /holaTodos
(El "Hola mundo" y "Hola todos" nunca fallan)
Y listo, la clase está creada. Como ahora vienen las clases de java se pueden declarar sin más archivos de configuración (algún archivo de despliegue o xml que configure los websockets) entonces se pudo haber creado una clase simple y a ella colocarle las anotaciones necesarias.
Con el WebSocket esto se hace más simple.
Es decir:
Escribiremos este código co
n algunas anotaciones del WebSocket:
Código:https://pastebin.com/9bbPPhUw
Notemos que - gracias a las anotaciones - ya no necesitamos implementar ni extender alguna clase. Basta con describir la anotación, Java sabrá que hacer con ese método.
Código: https://pastebin.com/CAgYxzqX
Si estamos con Chrome activemos la consola de desarrollo con la tecla F12. Veremos en la pestaña de NetWork solo ha tenido dos peticiones, la primera es la misma HTML y la segunda es la conexión al WebSocket... y tiene estado pendiente!
Hacemos clic en ese nodo para ver el detalle. Podremos ver la cabecera de conexión...
... y los frames de comunicación. Cada vez que escribimos un mensaje en el input veremos cómo se envían los frames entre el servidor y el cliente.
Lo que haremos es colocar en el servidor un EJB que cada cierto tiempo envíe una comunicación a los clientes. Para ello haremos que nuestro ServerEndPoint sea un ejb singleton, y colocamos un método programado para que envíe cada 10 segundos un mensaje. Ahora, para saber quienes están conectados, debemos crear una lista de todas las sesiones. Cada vez que se ejecuta el evento
Aquí el código del Servidor:
Código: https://pastebin.com/6UFi1gHv
Y el lado del cliente es lo más simple que puede haber:
Código: https://pastebin.com/ZuSZBkL9
Ahora lo ejecutamos, abrimos desde un navegador, luego abrimos el mismo enlace desde otro navegador y veremos el efecto.
No se qué opinan ustedes, pero para mi es la mejor solución Cliente/Servidor que haya visto para Web.
Mi opinión es que esta tecnología debería enseñarse a la nueva generación de desarrolladores web, y que AJAX sea tomado como un tema de historia.
Además, me he basado de otros links del mismo autor y otros ejemplos.
https://java.net/projects/apuntes/downloads/download/web/WebSocketsDemoWeb.tar.gz
Luego subiré el código en el Mercurial de java.net.
Buen día y bendiciones a todos!
Ya que estamos cerca del lanzamiento de Java EE 7 implementado en GlassFish 4.0, veremos un pequeño esbozo de esta tecnología.
WebSockets no es nuevo. Ya existe una norma en W3C que regula su implementación (aunque aún está en revisión, creo que su uso será como el HTML5.. todos lo usan asumiendo que está aprobado). Existen plugins en JQuery para consumirlos, Dojo Toolkit ya lo tiene implementado en su extensión Dojox; en los navegadores desde las versiones Chrome 4, Firefox 8, y Safari 5 ya está implementado (no responderé sobre MSIE)... ahora nos falta el lado del servidor, y esto es lo que veremos en este post. En la versión Java EE 7 vendrá como API para poder montar nuestro servicio WebSockets.
Preparando el Software
A la fecha de este post, he utilizado la versión desarrollo de NetBeans. (Cuando ya sea oficial, pueden descargar la versión completa). Debemos descargar la versión completa para la plataforma, es decir, la de Windows (si usamos Windows), la de Linux (si usamos Linux), etc.. pero no la versión .zip, ya que en esta no viene incluido el GlassFish.Después de instalarlo, nos preparamos para crear nuestro primer proyecto Web.
Proyecto Web
Creamos nuestro proyecto llamado WebSocketsDemoWeb y usamos el servidor "GlassFish Server 4.0" y elegimos la versión Java EE: Java EE 7 Web.... y le damos clic en "Finish".
Ahora, crearemos nuestra clase que será el punto de acceso al WebSocket. Creamos nuevo archivo desde File > New (Ctrl+N), y de la categoría "Web" seleccionamos "WebSocket Endpoint"
... clic en "Next".
Ahora debemos declarar las característica que tendrá nuestro WebSocket, como el nombre de la clase, la ruta del websocket, etc.
nombre de clase: HolaTodosEndPoint
paquete: com.apuntesdejava.websocket
WebSocket URI_: /holaTodos
(El "Hola mundo" y "Hola todos" nunca fallan)
Y listo, la clase está creada. Como ahora vienen las clases de java se pueden declarar sin más archivos de configuración (algún archivo de despliegue o xml que configure los websockets) entonces se pudo haber creado una clase simple y a ella colocarle las anotaciones necesarias.
Ciclo de vida de una conexión WebSocket
Las conexiones AJAX con RESTful o SOAP (y toda aplicación web) tienen esta particularidad:- El cliente se conecta al servidor,
- se establece la comunicación,
- el cliente hace el requerimiento,
- el servidor responde
- y terminó la conexión.
Con el WebSocket esto se hace más simple.
Es decir:
- El cliente inicia la conexión con el servidor
- Ambos se comunican. El cliente al servidor o el servidor al cliente.
- Se termina la conexión.
Implementando el WebSocket
Ahora nos toca escribir el código que estará del lado del servidor.Escribiremos este código co
n algunas anotaciones del WebSocket:
Código:https://pastebin.com/9bbPPhUw
Notemos que - gracias a las anotaciones - ya no necesitamos implementar ni extender alguna clase. Basta con describir la anotación, Java sabrá que hacer con ese método.
Implementado el cliente
En el lado del cliente lo haremos usando HTML5, así que funcionará con FF, GC y Safari (sorry MSIE). El código es bastante simple, y está comentado para no perder el hilo.Código: https://pastebin.com/CAgYxzqX
Probando la aplicación
Bastará con ejecutar la aplicación.Si estamos con Chrome activemos la consola de desarrollo con la tecla F12. Veremos en la pestaña de NetWork solo ha tenido dos peticiones, la primera es la misma HTML y la segunda es la conexión al WebSocket... y tiene estado pendiente!
Hacemos clic en ese nodo para ver el detalle. Podremos ver la cabecera de conexión...
... y los frames de comunicación. Cada vez que escribimos un mensaje en el input veremos cómo se envían los frames entre el servidor y el cliente.
Broadcast a todos los conectados
Este ejemplo es bastante interesante, ya que la idea es enviar un mensaje a todos los usuarios conectados. A diferencia del ejemplo anterior - donde el cliente espera una respuesta de la petición que ha hecho - este ejemplo solo espera que el servidor le diga algo. Notaremos que el cliente no tiene que hacer ni nada, ni tampoco estará consultando cada cierto tiempo al servidor si hay mensajes nuevos.Lo que haremos es colocar en el servidor un EJB que cada cierto tiempo envíe una comunicación a los clientes. Para ello haremos que nuestro ServerEndPoint sea un ejb singleton, y colocamos un método programado para que envíe cada 10 segundos un mensaje. Ahora, para saber quienes están conectados, debemos crear una lista de todas las sesiones. Cada vez que se ejecuta el evento
@OnOpen
se recibirá como parámetro la sesión y se agregará a una lista; y cada vez que se llame al evento @OnClose
, haremos que cierra la conexión y quitamos el evento de la lista.Aquí el código del Servidor:
Código: https://pastebin.com/6UFi1gHv
Y el lado del cliente es lo más simple que puede haber:
Código: https://pastebin.com/ZuSZBkL9
Ahora lo ejecutamos, abrimos desde un navegador, luego abrimos el mismo enlace desde otro navegador y veremos el efecto.
No se qué opinan ustedes, pero para mi es la mejor solución Cliente/Servidor que haya visto para Web.
Conclusión
En este post solo se vió algo muy simple de implementar, pero podemos ir más allá. Por ejemplo, podemos notificar alertas a los clientes - sea web o mobil (que podríamos verlo en otro post) - enviar objetos (que también será tema de otro post), etc.Mi opinión es que esta tecnología debería enseñarse a la nueva generación de desarrolladores web, y que AJAX sea tomado como un tema de historia.
Referencias
Como yo no me invento estas cosas, naturalmente las he tomado de alguien. Arun Gupta (@arungupta) ha prestando varias presentaciones sobre Java EE 7 que es muy conveniente revisarlas.Además, me he basado de otros links del mismo autor y otros ejemplos.
- WebSocket and Java EE 7 - Getting Ready for JSR 356 (TOTD #181) (Referencia antigua, pero válida para comprender el concepto)
- Building WebSocket Apps in Java using JSR 356
- Ejemplos de Tyrus, biblioteca que implementa el WebSocket API en GlassFish 4.0
Código fuente
Y por si las dudas, aquí el código fuente del proyecto. Recuerden utilizar GlassFish 4.0 y que el IDE sea compatible con Java EE .https://java.net/projects/apuntes/downloads/download/web/WebSocketsDemoWeb.tar.gz
Luego subiré el código en el Mercurial de java.net.
Buen día y bendiciones a todos!
Comentarios
Publicar un comentario
Si quieres hacer una pregunta más específica, hazla en los foros que tenemos habilitados en Google Groups
Ah! solo se permiten comentarios de usuarios registrados. Si tienes OpenID, bienvenido! Puedes obtener su OpenID, aquí: http://openid.net/