how to capture subscribe event in my webSocket server with Spring 4

sinedsem picture sinedsem · Jan 7, 2015 · Viewed 10.5k times · Source

I did a simple web socket communication with spring 4, STOMP and sock.js, following this https://spring.io/guides/gs/messaging-stomp-websocket/

Now I want to upgrade it to simple chat. My problem is that when user subscribes to new chat room, he should get past messages. I don't know how to capture the moment when he subscribed to send him the list of the messages.

I tried using @MessageMapping annotation, but didn't reach any success:

@Controller
public class WebSocketController {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;


    @MessageMapping("/chat/{chatId}")
    public void chat(ChatMessage message, @DestinationVariable String chatId) {
        messagingTemplate.convertAndSend("/chat/" + chatId, new ChatMessage("message: " + message.getText()));
    }

    @SubscribeMapping("/chat")
    public void chatInit() {
        System.out.println("worked");
        int chatId = 1; //for example
        messagingTemplate.convertAndSend("/chat/" + chatId, new ChatMessage("connected"));
    }

}

Then I created that:

@Controller
public class ApplicationEventObserverController implements ApplicationListener<ApplicationEvent> {
    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        System.out.println(applicationEvent);
    }
}

It works, but captures all possible events, I don't think it is a good practice.

So, my question can be rephrased: how to send initial data when user subscried to sth?

Answer

Sergi Almar picture Sergi Almar · Jan 8, 2015

You can return anything directly to a client when it subscribes to a destination using a @SubscribeMapping handler method. The returned object won't go to the broker but will be sent directly to the client:

@SubscribeMapping("/chat")
public Collection<ChatMessage> chatInit() {
    ...
    return messages;
}

On the client side:

socket.subscribe("/app/chat", function(message) {
    ...
});

Check out the chat example on GitHub, which shows this exact scenario.