websockets ejemplo crear java websocket jetty

crear - websocket javascript ejemplo



Jetty Websockets: enviar correctamente mensajes asíncronos al manejar conexiones no confiables (1)

Desafortunadamente, el protocolo WebSocket, que es un protocolo de aprobación de mensajes, no está diseñado para este nivel de matiz entre los mensajes.

El primer mensaje DEBE completarse antes de que pueda pensar en enviar el siguiente mensaje. Entonces, si tiene un mensaje en proceso, entonces no hay forma de cancelar ese mensaje de manera segura.

En el mejor de los casos, podría existir una API para truncar ese mensaje con una CONTINUACIÓN / carga útil vacía / fin = verdadero.

Pero incluso entonces, el punto extremo remoto no sabría que cancelaste el mensaje, solo vería un mensaje parcial.

La detección de problemas de conectividad se maneja mejor con eventos de nivel del sistema operativo (como los intentos de conectividad de Android), o a través de un PING websocket periódico (que se inserta delante de la línea para los marcos de websocket salientes).

Sin embargo, incluso con PING, si su marco de websocket saliente está en progreso, ni siquiera se puede enviar el PING hasta que el marco de websocket termine de enviarse.

RemoteEndpoint.flush() intentará eliminar cualquier mensaje (y fotograma) pendiente, no borrará los mensajes (o fotogramas) pendientes.

En cuanto a detectar si el cliente recibió el mensaje, deberá implementar algún tipo de ACK de mensaje en su propia capa para verificar que el protocolo no tenga tal concepto. (Algunos libs / apis construidos sobre websocket han implementado ACK de mensaje en esa capa. La extensión de invocación de mensaje comed viene a la mente como un ejemplo del mundo real)

¿Qué tipo de situación estás tratando de resolver?

Quizás el uso de RemoteEndpoint.sendPartialString(String, boolean) o RemoteEndpoint.sendPartialBytes(ByteBuffer, boolean) para enviar marcos más pequeños de todo el mensaje podría ser útil para usted. Sin embargo, es posible que el otro lado no tenga una API que pueda leer esos cuadros parciales (p. Ej .: Javascript en un navegador).

Estoy usando Jetty 9.3.5 y me gustaría saber cuál es la forma correcta de manejar conexiones no confiables al enviar mensajes de websocket, específicamente: noté casos en los que una conexión de websocket no se cierra normalmente, por lo que, aunque el cliente está fuera de servicio , lleva mucho tiempo hasta que onClose () se desencadene en el servidor (por ejemplo, un usuario cierra la tapa de la computadora portátil y la pone en modo de espera; puede llevar de 1 a 2 horas hasta que se reciba el evento cerrado en el servidor) .

Por lo tanto, como el cliente aún está registrado, el servidor sigue enviando mensajes que comienzan a acumularse. Esto se convierte en un problema al enviar una gran cantidad de mensajes.

He probado el envío de mensajes de bytes con:

Session.getRemote().sendBytes(ByteBuffer, WriteCallback) Session.getRemote().sendBytesByFuture(ByteBuffer);

Para simular la conexión hacia abajo en un lado (es decir, el usuario pone la computadora portátil en modo de espera), en Linux, asigné una dirección IP a la interfaz eth0, comencé a enviar los mensajes y luego los bajé:

ifconfig eth0 192.168.1.1 ifconfig eth0 up --- start sending messages (simple incremented numbers) and connect using Chrome browser and print them --- ifconfig eth0 down

De esta forma: los mensajes seguían siendo enviados por Jetty, el cliente de Chrome no los recibió, onCllose o onError no se activaron en el servidor

Mis preguntas con respecto a Jetty son:

  1. ¿Hay alguna manera de borrar los mensajes en cola que no se entregaron? Lo intenté, pero sin suerte:

    Session.getRemote (). Flush ();

  2. ¿Se puede establecer un número máximo de mensajes en cola? He intentado:

    WebSocketServletFactory.getPolicy (). SetMaxBinaryMessageBufferSize (1)

  3. ¿Puedo detectar si el cliente no recibe el mensaje? (o si la conexión está en un estado anormal, digamos) lo he intentado:

    session.getRemote().sendBytes(bb, new WriteCallback() { @Override public void writeSuccess() { //print success } @Override public void writeFailed(Throwable arg0) { //print fail } });

Pero esto imprime éxito a pesar de que los mensajes no se reciben.

También traté de usar, pero no pude encontrar una solución:

factory.getPolicy().setIdleTimeout(...); factory.getPolicy().setAsyncWriteTimeout(3000); sendPing()

¡Gracias por adelantado!