StompFrameHandler non ottiene payload dal messaggio

voti
2

Finalmente ho il mio cliente websocket connessione al punto finale, ma non riesco a estrarre messaggio payload. Posso ottenere le intestazioni ma payload non viene riconosciuto.

Il mio cliente WebSocket appare come di seguito:

    WebSocketTransport webSocketTransport = new WebSocketTransport(standardWebSocketClient);
    SockJsClient sockJsClient = new SockJsClient(Arrays.asList(webSocketTransport));
    WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient);

    stompClient.setMessageConverter(new StringMessageConverter());

    StompSessionHandler sessionHandler = new MyStompSessionHandler();
    ListenableFuture<StompSession> connect = stompClient.connect(URL, sessionHandler);

        StompSession stompSession = connect.get();
        System.out.println(sessionId:  + stompSession.getSessionId());

        String path = /queue/orders;

        stompSession.subscribe(path, new MySimpleStompFrameHandler());

Stomp Handler Telaio:

    private class MySimpleStompFrameHandler implements StompFrameHandler {

    @Override
    public Type getPayloadType(StompHeaders stompHeaders) {
        System.out.println(Headers  + stompHeaders.toString());
        return String.class;
    }

    @Override
    public void handleFrame(StompHeaders stompHeaders, Object payload) {
        System.out.println(Msg  + payload.toString());
        completableFuture.complete(payload.toString());
    }
}

Ho intestazioni scritto nel terminale, ma non c'è niente da metodo handleFrame. Qualche idea ?

A cura: dopo il debug vedo che il problema è in classe DefaultStompSession che usa la mia implementazione di frameHandler

    private void invokeHandler(StompFrameHandler handler, Message<byte[]> message, StompHeaders stompHeaders) {
    if (message.getPayload().length == 0) {
        handler.handleFrame(stompHeaders, null);
        return;
    }
    Type type = handler.getPayloadType(stompHeaders);
    Class<?> payloadType = ResolvableType.forType(type).resolve();
    Object object = getMessageConverter().fromMessage(message, payloadType);
    if (object == null) {
        throw new MessageConversionException(No suitable converter, payloadType= + payloadType +
                , handlerType= + handler.getClass());
    }
    handler.handleFrame(stompHeaders, object);
}

Il problema è che dopo questa linea Type type = handler.getPayloadType(stompHeaders);Dopo che nulla di più viene eseguito e il mio programma termina così handleFrame () non viene neanche eseguita. Cosa c'è di sbagliato c'è? Magari con Tipo tornato da getPayloadType - scelgo String perché penso che ogni messaggio può essere presentata come stringa.

È pubblicato 29/01/2018 alle 11:16
dall'utente
In altre lingue...                            


4 risposte

voti
0

Esiste un problema strano con Stomp Java.

@Override
public Type getPayloadType(StompHeaders stompHeaders) {
    System.out.println("Headers " + stompHeaders.toString());
    return String.class;
}

Dovrebbe essere sia

@Override
public Type getPayloadType(StompHeaders stompHeaders) {
    System.out.println("Headers " + stompHeaders.toString());
    return Object.class;
}

o

@Override
public Type getPayloadType(StompHeaders stompHeaders) {
    System.out.println("Headers " + stompHeaders.toString());
    return byte[].class;
}
Risposto il 24/02/2018 a 18:11
fonte dall'utente

voti
0

Ho avuto un problema simile.

Il problema era che avevo specificato stompClient.setMessageConverter(new StringMessageConverter());, mentre un JSON è stata approvata come payload.

Soluzione (per il mio problema): stompClient.setMessageConverter(new MappingJackson2MessageConverter());

Che cosa si può fare per trovare una soluzione:

  • Gettare (o log) quando viene attivato un'eccezione. Per il vostro caso, si dovrebbe aggiungere l'override del metodo seguente in MyStompSessionHandler:

    @Override
    public void handleException(StompSession session, StompCommand command, StompHeaders headers, byte[] payload, Throwable exception) {
        throw new RuntimeException("Failure in WebSocket handling", exception);
    }
    
  • Durante il debug invokeHandler, controllare il contenuto del carico utile. Se siete in grado di eseguire il codice, si esegue questa operazione eseguendo new String((byte[]) message.getPayload()).

Risposto il 02/11/2018 a 12:24
fonte dall'utente

voti
0

Ho avuto il tuo punto è necessario estendere StompSessionHandlerAdapterl'attuazione StompFrameHandler.

Ho provato qualcosa per te:

public class MySimpleStompFrameHandler extends StompSessionHandlerAdapter implements StompFrameHandler {

private Logger logger = LogManager.getLogger(MyStompSessionHandler.class);

@Override
public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
    System.out.println("Connected");
}

@Override
public void handleException(StompSession session, StompCommand command, StompHeaders 
 headers, byte[] payload, Throwable exception) {
    logger.error("Got an exception", exception);
}

@Override
public Type getPayloadType(StompHeaders headers) {
    return <payload_type>.class;
}

@Override
public void handleFrame(StompHeaders headers, Object payload) {
    <payload_type> msg = (<payload_type>) payload;
    System.out.println(msg);
    logger.info("Received : " + msg);
}

}

Dove payload_typeè la classe definita dall'utente che si desidera convertire i dati flusso

Buono per andare !!

Risposto il 26/08/2019 a 07:35
fonte dall'utente

voti
0

Condivido la mia realizzazione, spero di essere utile. Non ho fissato un messageconverter e fatto la mia implementazione personalizzata del metodo di handleFrame

    WebSocketClient client = new StandardWebSocketClient();
    WebSocketStompClient stompClient = new WebSocketStompClient(client);
    StompSessionHandler sessionHandler = new MyStompSessionHandler(prop);
    WebSocketHttpHeaders webSocketHttpHeaders = new WebSocketHttpHeaders();
    webSocketHttpHeaders.add("Authorization", "Bearer " + token);

    StompSession session = stompClient.connect(endpoint, webSocketHttpHeaders, sessionHandler).get();

e quindi la gestione del messaggio inviato, nel mio caso un oggetto JSON String

    @Override
    public Type getPayloadType(StompHeaders headers) {
        return null;
    }

    @Override
    public void handleFrame(StompHeaders headers, Object payload) {
        String cadena = new String((byte[]) payload);
        JsonParser parser = new JsonParser();
        JsonObject obj = parser.parse(cadena).getAsJsonObject();
        System.out.println(obj.toString());
    }   
Risposto il 04/09/2019 a 17:38
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more