websockets example tomcat websocket stomp spring-websocket java-websocket

tomcat - example - Conexión a Stomp sobre WebSockets implementado usando Spring 4 desde el cliente Java



websocket java example (1)

Recibí una aplicación web, implementada con Spring usando STOMP a través de WebSockets Messaging, similar a lo que se describe here (con RabbitMQ en el servidor). Se ejecuta en Tomcat, y puedo conectarme a la aplicación utilizando URL regulares (por ejemplo, http://host/server/ ). También me dieron un cliente de demostración: una página JSPX, que utiliza Modernizr WebSockets y SockJS. El código de conexión en el cliente de demostración se ve así:

if (Modernizr.websockets) { socket = new WebSocket(''ws://host/server/endpointx''); } else { socket = new SockJS(''/server/endpointy''); } stompClient = Stomp.over(socket); stompClient.connect(headers, function(frame) { ... }); ....

El cliente de demostración funciona bien (cuando cargo la página JSPX en el navegador, puedo conectarme al servidor). Pero mi objetivo es conectarme al mismo servidor utilizando alguna biblioteca STOMP de Java. El problema es que las bibliotecas que probé, requieren el host y el puerto como parámetros de conexión: por ejemplo, con la biblioteca ActiveMQ Stomp :

StompConnection connection = new StompConnection(); connection.open("host", port); connection.connect(new HashMap<String, String>());

Si especifico el port como 61613 , la conexión se realiza correctamente, pero golpeo a RabbitMQ directamente, no a mi servidor (no es lo que quiero). Si especifico 8080 (u 80 ), en la conexión obtengo un error

java.io.EOFException en java.io.DataInputStream.readByte (Fuente desconocida) en org.apache.activemq.transport.stomp.StompWireFormat.unmarshal (StompWireFormat.java:137) en org.apache.activemq.transport.stomp.Stomp. .receive (StompConnection.java:77) en org.apache.activemq.transport.stomp.StompConnection.receive (StompConnection.java:68) en org.apache.activemq.transport.stomp.stompConnection.connect (StompConnection.java:139 ) en .... stomp.impl.activemq.ActiveMQStompDriver.connect (ActiveMQStompDriver.java:39) ... 25 más

y la traza muestra que esto se debe a que la trama CONNECT nunca recibe una trama CONNECTED esperada (de hecho, no recibe nada de vuelta).

Así que estoy desconcertado: ¿estoy usando un puerto equivocado? ¿O lidiar con alguna incompatibilidad con la biblioteca? ¿O debo indicar de alguna manera a Tomcat que deseo actualizar la conexión HTTP a WebSockets ?

Si la pregunta anterior es difícil de responder, entonces esta es igualmente útil: ¿cómo me conecto a la aplicación Spring con STOMP a través del canal de mensajería WebSockets que se ejecuta en Tomcat usando Java?


Recibí una aplicación web, implementada con Spring usando STOMP a través de WebSockets Messaging, similar a lo que se describe aquí (con RabbitMQ en el servidor). Se ejecuta en Tomcat, y puedo conectarme a la aplicación utilizando URL regulares (por ejemplo, http://host/server/ ).

Esto es sólo para referencia más adelante en la respuesta:

Browser -> WebSocket -> Spring STOMP Broker Relay -> RabbitMQ

El ejemplo de trabajo crea un cliente Javscript en el navegador del usuario final. Se conecta a través de WebSockets a su servidor Tomcat y Spring STOMP Broker Relay en su aplicación. El relé, como su nombre lo indica, retransmite los mensajes STOMP que recibe a través del WebSocket a un socket real que está conectado a RabbitMQ (también a través de STOMP).

También me dieron un cliente de demostración: una página JSPX, que utiliza Modernizr WebSockets y SockJS.

No es relevante para la respuesta, pero no necesita verificar si WebSockets es compatible con el navegador del cliente. SockJS hará esto por usted y elegirá automáticamente el mejor canal para usar. En cualquier navegador moderno que no esté detrás de un proxy restrictivo, será WebSockets.

Pero mi objetivo es conectarme al mismo servidor utilizando alguna biblioteca STOMP de Java. El problema es que las bibliotecas que probé, requieren host y puerto como parámetros de conexión

Dudo que un cliente Java STOMP esté diseñado para funcionar en este escenario (aunque todo es posible). Normalmente , un cliente Java STOMP ejecutará el lado del servidor o en algún lugar que simplemente se conectará directamente al servidor STOMP, en su caso, eso significaría conectarse directamente a RabbitMQ.

Usted mencionó ser capaz de conectarse directamente a Rabbit, por lo que esa sería una posible solución aquí (dijo que no quería hacer esto, pero no por qué, no dude en aclarar ese punto en un comentario). Si su código se ejecuta en el lado del servidor, este es definitivamente el camino a seguir. Pasar por un canal WebSocket y el relé de broker Spring solo agregaría un salto adicional y una latencia innecesaria.

Otra solución sería utilizar un cliente Java que pueda comunicarse a través de WebSockets y STOMP. Solo recomendaría esto si su código Java se ejecuta como un cliente remoto en algún lugar y no tendrá acceso para hablar directamente con RabbitMQ.

Así que estoy desconcertado: ¿estoy usando un puerto equivocado? ¿O lidiar con alguna incompatibilidad con la biblioteca? ¿O debo indicar de alguna manera a Tomcat que deseo actualizar la conexión HTTP a WebSockets?

61613 es el puerto correcto para comunicarse con RabbitMQ directamente si eso es lo que quiere hacer. El puerto para establecer una conexión WebSocket es solo el puerto HTTP o HTTPS estándar en el que Tomcat está escuchando las conexiones (el valor predeterminado sería 8080/8443). No puedes hablar STOMP directamente a Tomcat, no entiende ese protocolo. Debe iniciar una conexión WebSocket y luego hablar STOMP a su aplicación (es decir, el relé de agente Spring STOMP).

Para hacer esto, necesita un cliente que sepa hablar WebSocket y un cliente que pueda hablar STOMP a través del canal WebSocket. Su cliente actual está intentando realizar una conexión de socket normal a Tomcat y no una conexión de WebSocket. Para tener éxito, primero deberá iniciar una conexión WebSocket y luego enviar mensajes STOMP a través de la conexión WebSocket.

Cuando su demostración se ejecuta en el navegador, la conexión de WebSocket es manejada por su navegador y SockJS, y su cliente de JavaScript STOMP habla sobre la conexión de WebSocket a la aplicación a través de STOMP (vea el diagrama ASCII más arriba).

Si la pregunta anterior es difícil de responder, entonces esta es igualmente útil: ¿cómo me conecto a la aplicación Spring con STOMP a través del canal de mensajería WebSockets que se ejecuta en Tomcat usando Java?

No creo que normalmente quieras hacer esto. Si tiene un código Java ejecutándose en Tomcat, sería más eficiente conectarse directamente a RabbitMQ (es decir, a su servidor STOMP) con su cliente Java STOMP.

STOMP sobre WebSockets es principalmente para que los clientes basados ​​en navegador que se ejecutan de forma remota puedan conectarse y enviar mensajes de forma fácil y segura sin necesidad de acceso directo a su servidor RabbitMQ.

¡Espero que ayude!