Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Spring Websockets

Spring Websockets

Talk from Sergi Almar at the Singapore Spring User Group

Avatar for SingaSUG

SingaSUG

July 29, 2015
Tweet

More Decks by SingaSUG

Other Decks in Technology

Transcript

  1. Agenda • HTML5  Realtime   • SSE   • Intro

      • Spring  4.2  support   • WebSocket   • Intro   • Spring  WebSocket   • Security 2
  2. Server-­‐sent  Events • uni-­‐directional  (server  push)   • built  on

     top  of  HTTP   • long-­‐lived  HTTP  connection   • EventSource  API
  3. Server-­‐sent  Events  Client var source = new EventSource('/metrics-sub'); source.onmessage =

    function(e) { var freeMemory = JSON.parse(e.data); $("#freeMem").text(freeMemory.value); }; 6
  4. Spring  SSE 7 @RequestMapping("/metrics-sub") public SseEmitter subscribeMetrics() { SseEmitter sseEmitter

    = new SseEmitter(); // Save emitter return sseEmitter; } • New  support  in  the  upcoming  Spring  4.2
  5. WebSockets • Real-­‐time  full  duplex  communication  over  TCP   •

    Uses  port  80  /  443  (URL  scheme:  ws://  and   wss://)   • Small  overhead  for  text  messages  (frames)   • 0x00  for  frame  start,  0xFF  for  frame  end  (vs   HTTP  1Kb)   • Ping  /  pong  frames  for  staying  alive 9
  6. The  Lifecycle 10 browser server HTTP can we upgrade to

    WebSocket? I want you to talk to me as well! HTTP 101 Yes! Talk WebSocket to me! WebSocket here’s a frame WebSocket here’s a frame WebSocket here’s a frame close connection
  7. WebSocket  Client  Side 12 var ws = new WebSocket("ws://www.springio.net/ws"); //

    When the connection is open, send some data to the server ws.onopen = function () { ws.send('Here I am!'); }; ws.onmessage = function (event) { console.log('message: ' + event.data); }; ws.onclose = function (event) { console.log('closed:' + event.code); };
  8. Spring  WebSockets • Why  should  we  use  Spring  WebSockets  instead

      of  plain  JSR-­‐356?   • Fallback  options  with  SockJS   • Support  for  STOMP  subprotocol     • Security  (with  Spring  Security)   • Integration  with  messaging  components  and   Spring  programming  style 13
  9. Endpoint  Configuration 14 @Configuration public class WebSocketConfig extends WebSocketMessageBrokerConfigurationSupport {

    public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint(“/ws") } ... } .withSockJS(); Use SockJS for fallback options
  10. Destination  Configuration 15 @Configuration public class WebSocketConfig extends WebSocketMessageBrokerConfigurationSupport {

    ... @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/queue/", "/topic/"); registry.setApplicationDestinationPrefixes("/app"); } } Broker destinations Application destinations
  11. The  Workflow 16 clientInboudChannel clientOutboundChannel WebSocket frame WebSocket 
 Endpoint

    sends message Message
 Handlers processed by sends to WebSocket frame
  12. Message  Handling 18 stompClient.send(‘/app/chat.message’, {}, JSON.stringify({message: ‘hi there’})); SEND destination:/app/chat.message

    content-length:22 {“message": "hi there"} @MessageMapping("/chat.message") public ChatMessage filterMessage(@Payload ChatMessage message, Principal principal) { checkProfanityAndSanitize(message); return message; }
  13. Handler  Method  Response 19 • SimpAnnotationMethodMessageHandler   doesn’t  know  about

     STOMP  semantics   • Return  values  are  sent  to  a  STOMP  message   broker  via  the  brokerChannel  (doesn’t  apply  to   @SubscriptionMapping)   • can  be  the  built-­‐in  simple  broker   • or  a  full  blown  message  broker
  14. Broker  Destinations • Two  options:   • Use  the  built-­‐in

     broker   • Use  a  full-­‐blown  message  broker 20 BrokerMessage Handler clientInboudChannel SimpAnnotation MethodMessage Handler brokerChannel
  15. Simple  Broker • Built-­‐in  broker,  only  supports  a  subset  of

      STOMP  commands   • Stores  everything  in  memory   • SimpleBrokerMessageHandler  will  be   subscribed  to  inboundClientChannel  and   brokerChannel 21 @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/queue/", "/topic/"); registry.setApplicationDestinationPrefixes("/app"); }
  16. Full  Blown  STOMP  Broker • Brokers  with  STOMP  support:  RabbitMQ,

      Apache  ActiveMQ,  HornetQ,  OpenMQ… 22 @Autowired private Environment env; @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableStompBrokerRelay("/queue/", "/topic/") .setRelayHost(env.getRequiredProperty("rabbitmq.host")) .setRelayPort(env.getRequiredProperty("rabbitmq.stompport", Integer.class)) .setSystemLogin(env.getRequiredProperty("rabbitmq.user")) .setSystemPasscode(env.getRequiredProperty("rabbitmq.password")) .setClientLogin(env.getRequiredProperty("rabbitmq.user")) .setClientPasscode(env.getRequiredProperty("rabbitmq.password")) .setVirtualHost(env.getRequiredProperty("rabbitmq.vh")); }
  17. WebSocket  Security  Config 26 @Configuration public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer

    { @Override protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) { messages .antMatchers(SimpMessageType.MESSAGE, ”/user/queue/errors").permitAll() .antMatchers("/topic/admin/*").hasRole("ADMIN") .anyMessage().hasRole("USER"); } } •