Reputation: 13970
I am using this guide to implement a simple Stomp client:
WebSocketClient webSocketClient = new StandardWebSocketClient();
WebSocketStompClient stompClient = new WebSocketStompClient(webSocketClient);
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.afterPropertiesSet();
stompClient.setTaskScheduler(taskScheduler); // for heartbeats
stompClient.setMessageConverter(new StringMessageConverter());
StompSessionHandler sessionHandler = new MySessionHandler();
stompClient.connect("ws://server/endpoint", sessionHandler);
// WAITING HERE
When connection completes it's supposed to report to MySessionHandler
asynchronously:
public class MySessionHandler extends StompSessionHandlerAdapter
{
@Override
public void afterConnected(StompSession session, StompHeaders connectedHeaders)
{
// WAITING FOR THIS
}
}
So question is: how the line WAITING HERE
should wait for the line WAITING FOR THIS
? Is there a specific Spring way of doing this? If not, which generic Java way fits here the best?
Upvotes: 6
Views: 11780
Reputation: 13970
The solution with latch works. Later I discovered that connect
function returns ListenableFuture<StompSession>
, so we can wait for session to be created like this:
ListenableFuture<StompSession> future =
stompClient.connect("ws://server/endpoint", sessionHandler);
StompSession session = future.get(); // <--- this line will wait just like afterConnected()
Upvotes: 8
Reputation: 501
You don need latch, nothing, afterConnected method will be executed only when connection is stablished.
My example:
URI stompUrlEndpoint = new URI("localhost:8080/Serv/enpoint");
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
//Calls initialize() after the container applied all property values.
taskScheduler.afterPropertiesSet();
StandardWebSocketClient webSocketClient = new StandardWebSocketClient();
List<Transport> transports = new ArrayList<>(2);
transports.add(new WebSocketTransport(webSocketClient));
SockJsClient sockJsClient = new SockJsClient(transports);
WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient);
stompClient.setMessageConverter(new SimpleMessageConverter()); // default converter: SimpleMessageConverter
// Configure a scheduler to use for heartbeats and for receipt tracking.
stompClient.setTaskScheduler(taskScheduler);
StompSessionHandlerImp stompSessionHandlerImp = new StompSessionHandlerImp();
ListenableFuture<StompSession> stompSessionFuture2 = stompClient.connect(stompUrlEndpoint.toString(), stompSessionHandlerImp);
try {
stompSession = stompSessionFuture.get(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
private class StompSessionHandlerImp extends StompSessionHandlerAdapter {
private StompSession session;
@Override
public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
this.session = session;
session.setAutoReceipt(true);
session.subscribe("/user/queue/bancaria.readcard", new StompFrameHandler() {
...
}
}
}
Upvotes: 1
Reputation: 11250
Maybe a java.util.concurrent.CountDownLatch
may solve your problem like this:
CountDownLatch latch = new CountDownLatch(1);
StompSessionHandler sessionHandler = new MySessionHandler(latch);
stompClient.connect("ws://server/endpoint", sessionHandler);
// wait here till latch will be zero
latch.await();
And your MySessionHandler
implementation:
public class MySessionHandler extends StompSessionHandlerAdapter {
private final CountDownLatch latch;
public MySessionHandler(final CountDownLatch latch) {
this.latch = latch;
}
@Override
public void afterConnected(StompSession session,
StompHeaders connectedHeaders) {
try {
// do here some job
} finally {
latch.countDown();
}
}
}
Upvotes: 8