Spring Websockets



Biju Kunjummen

Disclaimer!!


Content heavily copied from the followed sources:
  • http://www.slideshare.net/sergialmar/websockets-with-spring-4
  • https://github.com/rstoyanchev/spring-websocket-portfolio
  • Intro to Websocket applications with Spring Framework 4.0 - https://spring.io/blog/2014/01/21/springone2gx-2013-replay-intro-to-websocket-applications-with-spring-framework-4-0
  • Building Websocket browser apps with Spring: http://spring.io/blog/2013/10/23/webinar-replay-building-websocket-browser-applications-with-spring

WebSocket


demo: hello-world, tail-file

"mechanism for browser-based applications...

two-way communication with servers...

does not rely on multiple HTTP connections"


- RFC 6455, The WebSocket Protocol


WebSocket

  • A thin layer on top of raw TCP
  • Full Duplex, stateful connnection., stays open for an entire session
  • Stream of messages, not just raw bytes
  • Uses port 80, uses http for initial handshake

Reality!

  • Not supported in IE < 10 - http://caniuse.com/websockets
  • Issues with proxies
  • Not a replacement for Ajax/polling/long polling/comet
  • Socket is very low level to work on
  • Requires Messaging/Event driven architecture

When to use it


Low latency, high frequency of messages between client and server
  • Collaboration/Chat, Google docs
  • Games
  • Financial trading applications

Otherwise, chose polling/long polling/comet
  • Latest Story, latest tweet
						
	HANDSHAKE REQUEST

	GET /mychat HTTP/1.1
	Host: server.example.com
	Upgrade: websocket
	Connection: Upgrade
	Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
	Sec-WebSocket-Protocol: chat
	Sec-WebSocket-Version: 13
	Origin: http://example.com
						
					
						
	HANDSHAKE RESPONSE

	HTTP / 1.1 101 Switching Protocols
	Upgrade: websocket
	Connection: Upgrade
	Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
	Sec-WebSocket-Protocol: chat
						
					

Typical API Lifecycle Events


demo:spring-websocket-test
  • open - session established
  • message - new messages received
  • error - transport error
  • close - session closed

    • Symmetrical on the client and server sides

Java API for WebSocket - JSR-356

  • Tomcat 7.0.47+
  • Jetty 9.1+
  • Glassfish 4 with Tyrus WebSocket engine
  • Wildfly 8.0+

Sockjs

  • Emulate WebSocket API as close as possible
  • At least one streaming protocol per major browser
  • Polling in old browsers, hosts behind restrictive proxies

Sockjs URL Scheme


demo: spring-websocket-test
  • GET /echo
  • GET /echo/info
  • POST /echo/**server**/**session**/**transport**

WebSocket API - Very Low Level

  • Single WebSocket connection per client results in single @ServerEndpoint per application
  • limits you to one annotated class
  • Not the right level of abstraction-- much like plain Servlet is too course-grained
  • Raw WebSocket


    demo: spring-websocket-portfolio
  • A message is a blank page-- you can write anything (custom format?)
  • Can't provide useful annotations-- How to broadcast to some subset of users?
  • Spring's WebSocket API

    • Abstraction over WebSocket runtimes, Including JSR-356 containers, but not limited to it-
    • Supports transparent fallback options based on SockJS protocol
    • STOMP sub-protocol support
    • Abstractions for building messaging architectures-- Message, MessageChannel, MessageHandler

    STOMP Protocol

    • Simple protocol for asynchronous message passing
    • Originally for scripting languages (Ruby, Python)
    • Supported by message brokers
    • Suited for use on the web
    • Frames modelled on HTTP

    Stomp frame content
    
    COMMAND
    header1:value1
    header2:value2
    
    body^@
    
    

    Client-to-Server Commands

  • SEND
  • SUBSCRIBE
  • UNSUBSCRIBE
  • Server-to-Client Commands

  • MESSAGE
  • ERROR
  • RECEIPT
  • ACK
  • NACK
  • Sample client to server communication

    
    SEND
    destination: /queue/trade
    content-type: application/json
    content-length: 46
    
    {"action":"Buy","ticker":"CIS", "shares":"44"}^@
    
    
    

    Client Consumes a message(1)

    
    SUBSCRIBE
    id:sub-1
    destination: /topic/price.stock.*
    
    ^@
    
    
    

    Client Consumes a message(1)

    
    MESSAGE
    message-id:kdaldj
    subscription:sub-1
    destination:/topic/price.stock.CIS
    
    {"ticker":"CIS","price":"24"}^@
    
    
    

    STOMP vs Raw Websockets

    • Standard message format
    • Browser client support (e.g. stomp.js, msgs.js)
    • Common messaging patterns
    • Ability to incorporate (full-featured) message broker

    Spring - Configuring for Websocket with STOMP/SOCKJS fallback support

    
    @Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketDefaultConfig extends AbstractWebSocketMessageBrokerConfigurer {
    
    	@Override
    	public void configureMessageBroker(MessageBrokerRegistry config) {
    		config.enableStompBrokerRelay("/topic/");
    		config.setApplicationDestinationPrefixes("/app");
    	}
    
    	@Override
    	public void registerStompEndpoints(StompEndpointRegistry registry) {
    		registry.addEndpoint("/helloworld").withSockJS();
    	}
    }
    
    

    Spring - Sample servicing a request from the client

    
    @MessageMapping("/greetings")
    @SendTo("/topic/greetings")
    public String handleGreeting(@Payload String greeting) {
    	String message = "[" + getTimestamp() + "]:" + greeting;
    	oldMessages.add(message);
    	return message;
    }
    
    
    
    SEND
    destination:/app/greetings
    content-type:application/json
    content-length:11
    
    Hello world^@a
    
    

    Spring - Subscribing to messages


    demo: hello-world, sample-chat
    
    @SubscribeMapping("/oldmessages")
    public List<String> oldMessages() {
    	return Arrays.asList(oldMessages.toArray(new String[0]));
    }
    
    
    
    SUBSCRIBE
    destination:/app/oldmessages
    
    ^@
    
    

    References

    • http://www.slideshare.net/sergialmar/websockets-with-spring-4
    • https://github.com/rstoyanchev/spring-websocket-portfolio
    • Intro to Websocket applications with Spring Framework 4.0 - https://spring.io/blog/2014/01/21/springone2gx-2013-replay-intro-to-websocket-applications-with-spring-framework-4-0
    • Building Websocket browser apps with Spring: http://spring.io/blog/2013/10/23/webinar-replay-building-websocket-browser-applications-with-spring