package com.ankurm.ssews; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration; /** * Four lines of configuration that decide more than they look like they do. * * @see docs/04-stomp.md */ @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { // No setAllowedOrigins call at all. The handshake then permits same-origin requests // only -- and "same origin" is decided from the Origin header, which a non-browser // client does not send, so curl and the Java client are allowed while a page on // another site is not. Add setAllowedOriginPatterns("https://app.example.com") for a // real cross-origin front end; setAllowedOrigins("*") is rejected outright when // credentials are allowed. registry.addEndpoint("/ws"); // The SockJS variant is a SECOND endpoint on its own path. Registering .withSockJS() // on the same path does not give you both: SockJS wraps the URL in /{server}/{session} // and a plain WebSocket client pointed at it fails the handshake. registry.addEndpoint("/ws-sockjs").withSockJS(); } @Override public void configureMessageBroker(MessageBrokerRegistry registry) { // The simple broker. In-memory, single JVM, no persistence, no acknowledgement, and it // drops everything on restart. enableStompBrokerRelay(..) swaps in RabbitMQ or ActiveMQ // without touching a controller -- see ../rabbitmq for the broker side. registry.enableSimpleBroker("/topic", "/queue"); // Destinations a CLIENT sends to. /app/chat.send is routed to @MessageMapping; anything // starting with /topic or /queue goes straight to the broker and is NEVER seen by a // controller. Getting this backwards produces a message that vanishes with no error. registry.setApplicationDestinationPrefixes("/app"); // The prefix a client subscribes under for messages addressed to it alone. The client // subscribes to /user/queue/whisper; the broker rewrites that to a session-scoped // destination that no other session can subscribe to. registry.setUserDestinationPrefix("/user"); } @Override public void configureWebSocketTransport(WebSocketTransportRegistration registration) { // Defaults, restated so the numbers are visible in one place rather than discovered // when a 70 KB frame disappears. WebSocketTransportRegistration's own defaults are // 64 KB for both; see WebSocketLimitsTest for what exceeding them looks like. registration.setMessageSizeLimit(64 * 1024); registration.setSendBufferSizeLimit(512 * 1024); registration.setSendTimeLimit(20_000); } }