java - usar - websocket php jquery
Websocket(Jetty): cómo manejar los datos binarios en el lado del servidor que viene en trozos (1)
Necesito configurar un servidor websocket que pueda recibir datos de audio enviados por el cliente. Estoy usando embarcadero para esto.
Mi código de controlador:
{
@OnWebSocketClose
public void onClose(int statusCode, String reason) {
}
@OnWebSocketError
public void onError(Throwable t) {
}
@OnWebSocketConnect
public void onConnect(Session session) {
}
@OnWebSocketMessage
public void onMessage(String message) {
}
@OnWebSocketMessage
public void onMessage(bytes [] b) {
}
@OnWebSocketMessage
public void inputStream(InputStream is) {
}
}
Como el archivo de audio es bastante grande, el cliente los envía en fragmentos. Ahora, para cada onMessage(bytes [] b) {}
, se onMessage(bytes [] b) {}
.
Del lado del servidor, necesito agregar estos fragmentos y procesar el audio. Cómo puedo hacer eso.
Además, ¿cuál es la diferencia entre los onMessage(bytes [] b) {}
y onMessage(InputStream is) {}
.
Gracias,
Shantanu
De acuerdo con onMessage
javadoc , ambos onMessage(byte[] b)
y onMessage(InputStream is)
recibirán el mensaje completo :
si el método está manejando mensajes binarios:
- byte [] o ByteBuffer para recibir todo el mensaje
- InputStream para recibir todo el mensaje como una secuencia de bloqueo
Por lo tanto, si usa uno de estos métodos, Jetty volverá a ensamblar automáticamente los fragmentos y entregará todo el mensaje a su método (como un conjunto de byte[]
o un InputStream
).
El tamaño máximo del mensaje binario, puede recibir de esta manera, se establece con setMaxBinaryMessageSize
También tenga en cuenta que solo puede tener uno de estos métodos definidos en su clase Handler a la vez:
Cada punto extremo de websocket solo puede tener un método de manejo de mensaje para cada uno de los formatos de mensaje websocket nativos: texto, binario y pong.
Si desea procesar los datos tal como funcionan, debe usar la siguiente firma de método en su lugar:
@OnMessage
public void processUpload(byte[] b, boolean last, Session session) {
// process partial data here, which check on last to see if these is more on the way
}
y búfer manualmente sus datos (en la memoria o archivo de disco, etc.)
El cliente, a su vez, debe usar uno de los métodos sendPartialBytes para enviar el fragmento de datos por fragmento.
Si lo que observa es el método de "mensaje completo" (es decir, onMessage(byte[] b
) invocado para cada fragmento de datos, tal como lo envía el cliente, esto indica que el cliente no está utilizando las capacidades de protocolo para enviar mensajes fragmentados, y en su lugar, divide los datos de entrada y luego envía sus partes como mensajes de WS independientes , creando efectivamente su propio protocolo de nivel de aplicación para transmitir los datos en fragmentos.
En este caso, debe actualizar el cliente (si es una opción), hacer que use las capacidades normales del protocolo WS o implementar el mismo "protocolo de nivel de aplicación" que usa el cliente.
A continuación se muestra un ejemplo de punto final súper simple, que almacenará en búfer los datos de entrada hasta que se cierre el zócalo WS (esto implica que el cliente cerrará la conexión una vez que haya enviado todos los fragmentos).
@ServerEndpoint("/data")
public static class Handler {
private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@OnMessage
public void onMessage(byte[] message) throws IOException {
buffer.write(message);
}
@OnClose
public void onClose(Session session) throws IOException {
System.out.println(
buffer.toByteArray().length
);
}
}
Esta implementación también implica que se utiliza un ServerEndpointConfig.Configurator predeterminado, por lo que hay exactamente una instancia de Endpoint por conexión (como se documenta aquí ).
Una implementación más compleja podría querer reutilizar el socket para enviar múltiples archivos y especificar un mecanismo para indicar el inicio y el final de cada transmisión (por ejemplo, con un mensaje especialmente formateado), pero todo depende de cómo se implemente su cliente.