I have a fairly simple setup to test Stomp support in Spring.
I was planning on using JS to send messages to the queue and receive and handle them in Spring app. However, it doesn't seem to work for some reason.
JS client:
var ws = new SockJS('/hello');
client = Stomp.over(ws);
...
client.subscribe('jms.queue.test', function(message) {}
...
client.send("jms.queue.test", {}, "message");
Spring config (mostly useless at the moment, since i don't use /app
destination):
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableStompBrokerRelay("jms.topic", "jms.queue");
config.setApplicationDestinationPrefixes("/app");
config.setPathMatcher(new AntPathMatcher("."));
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/hello").withSockJS();
}
}
Spring Boot App:
@Component
public class BusinessLogic implements CommandLineRunner {
@Autowired
hulloController controller;
@Override
public void run(String... args) throws Exception {
stuff(args);
}
public void stuff(String[] args) throws InterruptedException {
Thread.sleep(20000);//sleep while spring boot fully initializes
controller.waitForGreet();
}
}
Controller (not a real @Controller
, i don't plan to use MVC):
@Component
public class hulloController {
private SimpMessagingTemplate template;
@Autowired
StompSessionHandler handler;
@Autowired
public hulloController(SimpMessagingTemplate template) {
this.template = template;
}
public void waitForGreet() {
System.out.println("Entered Listener");
WebSocketClient transport = new StandardWebSocketClient();
WebSocketStompClient stompClient = new WebSocketStompClient(transport);
stompClient.setMessageConverter(new StringMessageConverter());
stompClient.connect("ws://127.0.0.1:61613/stomp", handler);
}
}
And finally, the handler:
@Component
public class SessionHandler implements StompSessionHandler {
@Override
public void afterConnected(StompSession stompSession, StompHeaders stompHeaders) {
System.out.println("Connected!");
StompFrameHandler handler = new StompFrameHandler() {
@Override
public Type getPayloadType(StompHeaders stompHeaders) {
return null;
}
@Override
public void handleFrame(StompHeaders stompHeaders, Object o) {
System.out.println("received " + o.toString());
}
};
//StompSession.Subscription s = stompSession.subscribe("jms.queue.test", handler);
stompSession.send("jms.queue.test", "hello!");
}
...
}
If i comment the client.subscribe
part, client.send
works properly, message is received and rendered in JS, so the queue names and connection URL are fine. I also tried using SockJSClient
as a Transport but it doesn't help.
When i send messages from JS, for about 1 or 2 minutes half of them isn't showing up (as it would be if the subscription would be working), then JS starts receiving 100% of the messages.
I've seen plenty of almost identical code on github today, and i just don't see what the issue might be here.
So, apparently switching from implementing StompSessionHandler
to extending StompSessionHandlerAdapter
for my handler did the trick.
I have absolutely no idea why, but i guess this passage from Spring docs for StompSessionHandler
is there for a reason:
"Implementations of this interface should consider extending StompSessionHandlerAdapter."
//StompSession.Subscription s = stompSession.subscribe("jms.queue.test", handler);
stompSession.send("jms.queue.test", "hello!");
The STOMP over WebSocket is a an async
protocol.
You call there subscribe
and got to the send
. There is no guaranty that the subscription will happen already, when you start to send something to that destination.
Consider to use StompSession.Subscription
and its addReceiptTask()
to send messages to the destination after the confirmation for the subscription.
And you should enable StompSession.setAutoReceipt(true)
to make that working with your STOMP Broker.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With