| z, ? | toggle help (this) |
| space, → | next slide |
| shift-space, ← | previous slide |
| d | toggle debug mode |
| ## <ret> | go to slide # |
| c, t | table of contents (vi) |
| f | toggle footer |
| r | reload slides |
| n | toggle notes |
| p | run preshow |
JSR-356
@ServerEndpoint per application@RequestMapping?

SENDSUBSCRIBEUNSUBSCRIBEMESSAGEERRORRECEIPTACKNACK"Destination" Header"/queue/a", "/topic/a")


spring-messagingMessage, MessageChannel, MesageHandler, ...)
@Controller
public class GreetingController {
// Receive client messages to destination "/greeting"
@MessageMapping("/greeting")
public void greet(String greeting) {
}
}
@Controller
public class GreetingController {
// Receive client messages to destination "/greeting"
// Process + send to subscribers of "/topic/greetings"
@MessageMapping("/greeting")
@SendTo("/topic/greetings")
public String greet(String greeting) {
return "[" + getTimestamp() + "]: " + greeting;
}
}
"/topic/greetings" Subscriptions?
@Configuration
@EnableWebSocketMessageBroker
public class Config implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry r) {
r.addEndpoint("/stomp"); // WebSocket URL prefix
}
@Override
public void configureMessageBroker(MessageBrokerConfigurer c) {
c.enableSimpleBroker("/topic/"); // destination prefix
c.setAnnotationMethodDestinationPrefixes("/app");
}
}

@Controller
public class GreetingController {
@Autowired
private SimpMessagingTemplate template;
@RequestMapping(value="/greeting", method=POST)
public void greet(String greeting) {
String text = "[" + getTimeStamp() + "]:" + greeting;
this.template.convertAndSend("/topic/greeting", text);
}
}
@Controller
public class PortfolioController {
@SubscribeEvent("/positions")
public List<PortfolioPosition> getPositions(Principal user) {
Portfolio portfolio = ...
return portfolio.getPositions();
}
}
SUBSCRIBE, UNSUBSCRIBE, MESSAGE)

@Configuration
@EnableWebSocketMessageBroker
public class Config implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerConfigurer c) {
c.enableStompBrokerRelay("/queue/", "/topic/");
c.setAnnotationMethodDestinationPrefixes("/app");
}
// ...
}
CONNECT frame has authentication headers
@Controller
public class GreetingController {
@MessageMapping("/greeting")
@SendTo("/topic/greetings")
public String greet(String greeting, Principal user) {
return "[" + user + "] says: " + greeting;
}
}
@Controller
public class GreetingController {
// ...
@MessageExceptionHandler
@SendToUser("/queue/errors")
public String handleException(IllegalStateException ex) {
return ex.getMessage();
}
}
@Service
public class TradeService {
@Autowired
private SimpMessagingTemplate template;
public void executeTrade(Trade trade) {
String user = trade.getUser();
String dest = "/queue/position-updates";
TradeResult result = ...
this.template.convertAndSendToUser(user, dest, result);
}
}
@SendToUser("/queue/a")"/user/{user}/queue/a""/queue/a/" + unique queue-suffixCONNECTED frame provides that suffix
"/exchange/amq.direct/a"