SlideShare a Scribd company logo
1 of 40
Download to read offline
WebSockets with Spring 4
Sergi Almar
@sergialmar
Who I am
•

CTO @ Voz.io

•

Spring Certified Trainer

•

javaHispano Core Member

•

Spring I/O conference organiser
Collaborative Apps
Multiplayer Games
Multimedia Chat
Social Feeds
Sports Updates
Financial Tickets
Clickstream Data
Online Education
Location-based Apps
Real-Time Data on the Web
•

Polling

•

Long Polling / Comet

•

Flash
Problem

Applications need two-way communication
Too many connections and overhead with ajax / comet
WebSockets

two-way communication done right
WebSocket Protocol / RFC 6455
•

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
WebSocket Handshake
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!

client sends a WebSocket handshake request
HTTP/1.1 101 Switching Protocols!
Upgrade: websocket!
Connection: Upgrade!
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=!
Sec-WebSocket-Protocol: chat!

server response
JS WebSocket API
var ws = new WebSocket("ws://www.java2days.com/ws");!

!
// When the connection is open, send some data to the server!
ws.onopen = function () {!
ws.send('Here I am!');!
};!

!
// Log messages from the server!
ws.onmessage = function (event) {!
console.log('message: ' + event.data);!
};!

!
ws.onclose = function (event) {!
console.log('closed:' + event.code);!
};!
Java WebSocket Implementations
•

Multiple implementations before the standard

•

JSR-356 (May 2013)
•

Reference implementation Tyrus (bundled with
Glassfish 4)

•

Rewrite across containers (tomcat 8.0.0-RC5, Jetty
9.1…)
WebSockets.springify()
Spring WebSockets
•

WebSockets are now supported in Spring 4

•

Fallback options with SockJS

•

STOMP over WebSocket

•

Foundation for messaging architecture
WebSocket Handlers
public class EchoHandler extends TextWebSocketHandlerAdapter {!

!
@Override!
public void handleTextMessage(WebSocketSession session, !
! ! ! ! ! ! ! ! ! ! TextMessage message) throws Exception {!
session.sendMessage(message);!
}!
!
}
WebSocket Config
@Configuration!
@EnableWebSocket!
public class WsConfig implements WebSocketConfigurer {!

!
!

!

@Override!
public void registerWebSocketHandlers(!
! ! ! ! ! ! ! ! ! WebSocketHandlerRegistry registry) {!

!
registry.addHandler(new EchoHandler(), "/echo");!
}!
}!
Per-Session Handler
Previous example showed how to configure a global handler

•

•

but you may want to have a stateful per-session handler

@Configuration!
@EnableWebSocket!
public class WsConfig implements WebSocketConfigurer {!

!

!

@Bean!
DI
public WebSocketHandler echoHandler() {!
return new PerConnectionWebSocketHandler(EchoHandler.class);!
}!
@Override!
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {!
registry.addHandler(echoHandler(), "/echo");!
}!

}
Can anyone join the party?

http://caniuse.com/#feat=websockets / DEC 2013
SockJS

dude, where are my socks?
SockJS
•

Coherent, cross-browser, Javascript API for full duplex
communication.

•

Close to HTML5 WebSockets API

•

Client and server side implementation (ruby, node…
and also in spring-websockets)
SocksJS API
var sock = new SockJS('http://www.java2days.com/ws');!

!
sock.onopen = function() {!
sock.send('Here I am');
};!

!

!
sock.onmessage = function(event) {!
console.log('message', e.data);!
};!

!
sock.onclose = function() {!
console.log('close');!
};!
SockJS URLs
•

Base URL: /base_url

•

Info test: /base_url/info

•

Session URL: /base_url/server/session
Enabling SocksJS
@Configuration!
@EnableWebSocket!
public class WsConfig implements WebSocketConfigurer {!

!
!

!

@Override!
public void registerWebSocketHandlers(!
! ! ! ! ! ! ! ! ! WebSocketHandlerRegistry registry) {!

!
registry.addHandler(new EchoHandler(), “/echo”).withSockJS();!
}!
}!

MessageHandler doesn’t change
(SocketJsService delivers the message to the handler regardless of the protocol)
Problem
•

WebSockets are too low level and different from
HTTP / REST

•

We need asynchronous, event-driven, reactive
programming style

•

Mmmm, that sounds familiar: JMS, AMQP… 

but we still want to stick to the Spring MVC
programming model
Here’s were we are…
…but we want something like this
Solution
•

Stomp over WebSocket

•

Some Spring Integration types have been promoted to
the core
•
•

•

Message, MessageChannel, MessageHandler…
@MessageMapping, @SubscribeEvent…

New spring-messaging module
STOMP
STOMP
•

Simple interoperable protocol for asynchronous messaging

•

Supported by Apache ActiveMQ, RabbitMQ, HornetQ…

•

Frames modelled on HTTP

var socket = new SockJS('/myapp/echo');!
var client = Stomp.over(socket);

COMMAND!
header1:value1!
header2:value2!
!
Body^@!
Client Frames
•

SEND a message

•

SUBSCRIBE / UNSUBSCRIBE from destination

•

ACK / NACK the reception of a message (optional by
default)
Server Frames
•

Convey a MESSAGE from subscription to the client

•

Send RECEIPT when server has successfully
processed a client frame

•

Send an ERROR if something goes wrong
Configuration
!
@Configuration!
@EnableWebSocketMessageBroker!
public class Config implements WebSocketMessageBrokerConfigurer {!

!
@Override!
public void registerStompEndpoints(StompEndpointRegistry r){!
r.addEndpoint("/stomp");!
}!

!
@Override!
public void configureMessageBroker(MessageBrokerConfigurer c){!
c.enableSimpleBroker("/topic/");!
Subscriptions
c.setApplicationDestinationPrefixes("/app");!
processed by spring
}!

!
}!

simple broker
Sending Messages
stomp.js
stompClient.send("/app/trade", {}, JSON.stringify(trade));

prefix
SEND!
destination:/app/trade!
content-type:application/json!
content-length:47!

!
{"action":"Sell","ticker":"DELL","shares":"10"}!

supports ant-style patterns
@MessageMapping("/trade")!
public void executeTrade(Trade trade, Principal principal) {!
! trade.setUsername(principal.getName());!
! this.tradeService.executeTrade(trade);!
}
Handler Methods
•

Flexible handler method signatures
•

@PathVariable, @Header/@Headers, @Payload, Message, Principal

•

Message converters
@Controller!
public class ChatController {!

!
@MessageMapping("/message")!
public void sendMessage(String message, Principal principal) {!
// ...!
}!
}!
Handler Methods
•

Can also return a value
!
!
!

Return wrapped in a Message and sent to /topic/message
@MessageMapping("/message")!
public String sendMessage(String message) {!
return message.toUpperCase();!
}

!
•

Or define the destination with @SendTo
@MessageMapping("/message")!
@SendTo("/topic/spring-room")!
public String sendMessage(String message) {!
return message.toUpperCase();!
}!
Intercepting Subscriptions
stompClient.subscribe("/app/positions", function(message) {!
...!
});!
SUBSCRIBE!
id:sub-0!
destination:/app/positions!
@Controller!
public class PortfolioController {!

!
@SubscribeEvent("/positions")!
public List<Position> getPositions(Principal p) {!
Portfolio portfolio = ...!
return portfolio.getPositions();!
}!
}

sent directly to the client, not going
though the message broker
User destinations
•

User specific queues can be used
•
•

•

/user/** kind of paths
queues with unique id will be created

Useful to send user related information or errors

client.subscribe("/user/queue/private-messages", function(msg) {!
// ...!
});!

!
client.subscribe("/user/queue/errors", function(msg) {!
// ...!
});!
Sending to user
@Controller!
public class ChatController {!
Will be sent to /user/{username}/queue/message
!
@MessageMapping("/message")!
@SendToUser!
public String sendMessage(String message) {!
return message.toUpperCase();!
}!
!
@MessageExceptionHandler!
@SendToUser("/queue/errors")!
public String handleException(IllegalStateException ex) {!
return ex.getMessage();!
}!
!
}!
SimpMessagingTemplate
•

Sending messages without handler methods

template.convertAndSend("/topic/chat", message;!
template.convertAndSendToUser(user, dest, message;
Using a Message Broker
•

Previous configuration used Spring’s simple broker
•
•

•

Not suitable for clustering
Subset of STOMP

A message broker can be plugged-in instead
Message Broker Config
@Configuration!
@EnableWebSocketMessageBroker!
public class Config implements WebSocketMessageBrokerConfigurer{!
!
@Override!
public void configureMessageBroker(MessageBrokerConfigurer c){!
c.enableStompBrokerRelay("/queue/", "/topic/");!
c.setApplicationDestinationPrefixes("/app");!
}!
}
Thanks!
@sergialmar

More Related Content

What's hot

Spring Boot & WebSocket
Spring Boot & WebSocketSpring Boot & WebSocket
Spring Boot & WebSocket
Ming-Ying Wu
 
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Ryosuke Uchitate
 

What's hot (20)

Spring boot
Spring bootSpring boot
Spring boot
 
Spring boot - an introduction
Spring boot - an introductionSpring boot - an introduction
Spring boot - an introduction
 
[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기
[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기
[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Introduction to Spring Boot
Introduction to Spring BootIntroduction to Spring Boot
Introduction to Spring Boot
 
Spring Boot & WebSocket
Spring Boot & WebSocketSpring Boot & WebSocket
Spring Boot & WebSocket
 
Testing Spring Boot Applications
Testing Spring Boot ApplicationsTesting Spring Boot Applications
Testing Spring Boot Applications
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 
Spring Boot in Action
Spring Boot in Action Spring Boot in Action
Spring Boot in Action
 
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
 
Testing with Spring: An Introduction
Testing with Spring: An IntroductionTesting with Spring: An Introduction
Testing with Spring: An Introduction
 
Spring JMS
Spring JMSSpring JMS
Spring JMS
 
Asp.net MVC training session
Asp.net MVC training sessionAsp.net MVC training session
Asp.net MVC training session
 
Spring boot
Spring bootSpring boot
Spring boot
 
Spring boot jpa
Spring boot jpaSpring boot jpa
Spring boot jpa
 
Spring boot
Spring bootSpring boot
Spring boot
 
Authenticating Angular Apps with JWT
Authenticating Angular Apps with JWTAuthenticating Angular Apps with JWT
Authenticating Angular Apps with JWT
 
Spring MVC
Spring MVCSpring MVC
Spring MVC
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
WebAssembly Overview
WebAssembly OverviewWebAssembly Overview
WebAssembly Overview
 

Viewers also liked

SockJS Intro
SockJS IntroSockJS Intro
SockJS Intro
Ngoc Dao
 
Using SockJS(Websocket) with Sencha Ext JS
Using SockJS(Websocket) with Sencha Ext JSUsing SockJS(Websocket) with Sencha Ext JS
Using SockJS(Websocket) with Sencha Ext JS
Kazuhiro Kotsutsumi
 
Programming WebSockets - OSCON 2010
Programming WebSockets - OSCON 2010Programming WebSockets - OSCON 2010
Programming WebSockets - OSCON 2010
sullis
 
Creating a WebSocket-Chat-Application with Jetty Embedded - Techcamp 2014
Creating a WebSocket-Chat-Application with Jetty Embedded - Techcamp 2014Creating a WebSocket-Chat-Application with Jetty Embedded - Techcamp 2014
Creating a WebSocket-Chat-Application with Jetty Embedded - Techcamp 2014
Minh Nguyen Vo Cao
 
10 performance and scalability secrets of ASP.NET websites
10 performance and scalability secrets of ASP.NET websites10 performance and scalability secrets of ASP.NET websites
10 performance and scalability secrets of ASP.NET websites
oazabir
 

Viewers also liked (20)

Spring + WebSocket integration
Spring + WebSocket integrationSpring + WebSocket integration
Spring + WebSocket integration
 
Websockets and SockJS, Real time chatting
Websockets and SockJS, Real time chattingWebsockets and SockJS, Real time chatting
Websockets and SockJS, Real time chatting
 
SockJS Intro
SockJS IntroSockJS Intro
SockJS Intro
 
Realtime web application with java
Realtime web application with javaRealtime web application with java
Realtime web application with java
 
Using SockJS(Websocket) with Sencha Ext JS
Using SockJS(Websocket) with Sencha Ext JSUsing SockJS(Websocket) with Sencha Ext JS
Using SockJS(Websocket) with Sencha Ext JS
 
WebSockets and Java
WebSockets and JavaWebSockets and Java
WebSockets and Java
 
Programming WebSockets - OSCON 2010
Programming WebSockets - OSCON 2010Programming WebSockets - OSCON 2010
Programming WebSockets - OSCON 2010
 
Introduction to WebSockets
Introduction to WebSocketsIntroduction to WebSockets
Introduction to WebSockets
 
Introduction to WebSockets
Introduction to WebSocketsIntroduction to WebSockets
Introduction to WebSockets
 
Building Next Generation Real-Time Web Applications using Websockets
Building Next Generation Real-Time Web Applications using WebsocketsBuilding Next Generation Real-Time Web Applications using Websockets
Building Next Generation Real-Time Web Applications using Websockets
 
Creating a WebSocket-Chat-Application with Jetty Embedded - Techcamp 2014
Creating a WebSocket-Chat-Application with Jetty Embedded - Techcamp 2014Creating a WebSocket-Chat-Application with Jetty Embedded - Techcamp 2014
Creating a WebSocket-Chat-Application with Jetty Embedded - Techcamp 2014
 
Nuts and Bolts of WebSocket Devoxx 2014
Nuts and Bolts of WebSocket Devoxx 2014Nuts and Bolts of WebSocket Devoxx 2014
Nuts and Bolts of WebSocket Devoxx 2014
 
Spring Boot Update
Spring Boot UpdateSpring Boot Update
Spring Boot Update
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
HTML5 Real-Time and Connectivity
HTML5 Real-Time and ConnectivityHTML5 Real-Time and Connectivity
HTML5 Real-Time and Connectivity
 
10 performance and scalability secrets of ASP.NET websites
10 performance and scalability secrets of ASP.NET websites10 performance and scalability secrets of ASP.NET websites
10 performance and scalability secrets of ASP.NET websites
 
WebSockets in JEE 7
WebSockets in JEE 7WebSockets in JEE 7
WebSockets in JEE 7
 
HTML5 Night 2014 Web x Network Technology ( WebRTC )
HTML5 Night 2014 Web x Network Technology ( WebRTC )HTML5 Night 2014 Web x Network Technology ( WebRTC )
HTML5 Night 2014 Web x Network Technology ( WebRTC )
 
Welcome to the Black Hole of Bug Bounty Program
Welcome to the Black Hole of Bug Bounty ProgramWelcome to the Black Hole of Bug Bounty Program
Welcome to the Black Hole of Bug Bounty Program
 
PhoneGap Introduction
PhoneGap IntroductionPhoneGap Introduction
PhoneGap Introduction
 

Similar to WebSockets with Spring 4

WebSockets: The Current State of the Most Valuable HTML5 API for Java Developers
WebSockets: The Current State of the Most Valuable HTML5 API for Java DevelopersWebSockets: The Current State of the Most Valuable HTML5 API for Java Developers
WebSockets: The Current State of the Most Valuable HTML5 API for Java Developers
Viktor Gamov
 
Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)
Ran Mizrahi
 
HTML5 vs Silverlight
HTML5 vs SilverlightHTML5 vs Silverlight
HTML5 vs Silverlight
Matt Casto
 
Sparkling Water 5 28-14
Sparkling Water 5 28-14Sparkling Water 5 28-14
Sparkling Water 5 28-14
Sri Ambati
 

Similar to WebSockets with Spring 4 (20)

Nodejs and WebSockets
Nodejs and WebSocketsNodejs and WebSockets
Nodejs and WebSockets
 
Transforming WebSockets
Transforming WebSocketsTransforming WebSockets
Transforming WebSockets
 
Html 5 boot camp
Html 5 boot campHtml 5 boot camp
Html 5 boot camp
 
Websockets on the JVM: Atmosphere to the rescue!
Websockets on the JVM: Atmosphere to the rescue!Websockets on the JVM: Atmosphere to the rescue!
Websockets on the JVM: Atmosphere to the rescue!
 
WebSockets: The Current State of the Most Valuable HTML5 API for Java Developers
WebSockets: The Current State of the Most Valuable HTML5 API for Java DevelopersWebSockets: The Current State of the Most Valuable HTML5 API for Java Developers
WebSockets: The Current State of the Most Valuable HTML5 API for Java Developers
 
HTML5 WebSocket: The New Network Stack for the Web
HTML5 WebSocket: The New Network Stack for the WebHTML5 WebSocket: The New Network Stack for the Web
HTML5 WebSocket: The New Network Stack for the Web
 
GWT Web Socket and data serialization
GWT Web Socket and data serializationGWT Web Socket and data serialization
GWT Web Socket and data serialization
 
Going realtime with Socket.IO
Going realtime with Socket.IOGoing realtime with Socket.IO
Going realtime with Socket.IO
 
Intro to node.js - Ran Mizrahi (27/8/2014)
Intro to node.js - Ran Mizrahi (27/8/2014)Intro to node.js - Ran Mizrahi (27/8/2014)
Intro to node.js - Ran Mizrahi (27/8/2014)
 
Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)
 
HTML5 vs Silverlight
HTML5 vs SilverlightHTML5 vs Silverlight
HTML5 vs Silverlight
 
Maximize your Cache for No Cash
Maximize your Cache for No CashMaximize your Cache for No Cash
Maximize your Cache for No Cash
 
Web-Socket
Web-SocketWeb-Socket
Web-Socket
 
Apidaze WebRTC Workshop barcelona 21st april 2013
Apidaze WebRTC Workshop barcelona 21st april 2013Apidaze WebRTC Workshop barcelona 21st april 2013
Apidaze WebRTC Workshop barcelona 21st april 2013
 
Sparkling Water 5 28-14
Sparkling Water 5 28-14Sparkling Water 5 28-14
Sparkling Water 5 28-14
 
WebSocket Perspectives and Vision for the Future
WebSocket Perspectives and Vision for the FutureWebSocket Perspectives and Vision for the Future
WebSocket Perspectives and Vision for the Future
 
The HTML5 WebSocket API
The HTML5 WebSocket APIThe HTML5 WebSocket API
The HTML5 WebSocket API
 
CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009
 
Get Real: Adventures in realtime web apps
Get Real: Adventures in realtime web appsGet Real: Adventures in realtime web apps
Get Real: Adventures in realtime web apps
 
Cape Cod Web Technology Meetup - 2
Cape Cod Web Technology Meetup - 2Cape Cod Web Technology Meetup - 2
Cape Cod Web Technology Meetup - 2
 

Recently uploaded

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 

WebSockets with Spring 4

  • 1. WebSockets with Spring 4 Sergi Almar @sergialmar
  • 2. Who I am • CTO @ Voz.io • Spring Certified Trainer • javaHispano Core Member • Spring I/O conference organiser
  • 3. Collaborative Apps Multiplayer Games Multimedia Chat Social Feeds Sports Updates Financial Tickets Clickstream Data Online Education Location-based Apps
  • 4. Real-Time Data on the Web • Polling • Long Polling / Comet • Flash
  • 5. Problem Applications need two-way communication Too many connections and overhead with ajax / comet
  • 7. WebSocket Protocol / RFC 6455 • 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
  • 8. WebSocket Handshake 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! client sends a WebSocket handshake request HTTP/1.1 101 Switching Protocols! Upgrade: websocket! Connection: Upgrade! Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=! Sec-WebSocket-Protocol: chat! server response
  • 9. JS WebSocket API var ws = new WebSocket("ws://www.java2days.com/ws");! ! // When the connection is open, send some data to the server! ws.onopen = function () {! ws.send('Here I am!');! };! ! // Log messages from the server! ws.onmessage = function (event) {! console.log('message: ' + event.data);! };! ! ws.onclose = function (event) {! console.log('closed:' + event.code);! };!
  • 10. Java WebSocket Implementations • Multiple implementations before the standard • JSR-356 (May 2013) • Reference implementation Tyrus (bundled with Glassfish 4) • Rewrite across containers (tomcat 8.0.0-RC5, Jetty 9.1…)
  • 12. Spring WebSockets • WebSockets are now supported in Spring 4 • Fallback options with SockJS • STOMP over WebSocket • Foundation for messaging architecture
  • 13. WebSocket Handlers public class EchoHandler extends TextWebSocketHandlerAdapter {! ! @Override! public void handleTextMessage(WebSocketSession session, ! ! ! ! ! ! ! ! ! ! ! TextMessage message) throws Exception {! session.sendMessage(message);! }! ! }
  • 14. WebSocket Config @Configuration! @EnableWebSocket! public class WsConfig implements WebSocketConfigurer {! ! ! ! @Override! public void registerWebSocketHandlers(! ! ! ! ! ! ! ! ! ! WebSocketHandlerRegistry registry) {! ! registry.addHandler(new EchoHandler(), "/echo");! }! }!
  • 15. Per-Session Handler Previous example showed how to configure a global handler • • but you may want to have a stateful per-session handler @Configuration! @EnableWebSocket! public class WsConfig implements WebSocketConfigurer {! ! ! @Bean! DI public WebSocketHandler echoHandler() {! return new PerConnectionWebSocketHandler(EchoHandler.class);! }! @Override! public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {! registry.addHandler(echoHandler(), "/echo");! }! }
  • 16. Can anyone join the party? http://caniuse.com/#feat=websockets / DEC 2013
  • 18. SockJS • Coherent, cross-browser, Javascript API for full duplex communication. • Close to HTML5 WebSockets API • Client and server side implementation (ruby, node… and also in spring-websockets)
  • 19. SocksJS API var sock = new SockJS('http://www.java2days.com/ws');! ! sock.onopen = function() {! sock.send('Here I am'); };! ! ! sock.onmessage = function(event) {! console.log('message', e.data);! };! ! sock.onclose = function() {! console.log('close');! };!
  • 20. SockJS URLs • Base URL: /base_url • Info test: /base_url/info • Session URL: /base_url/server/session
  • 21. Enabling SocksJS @Configuration! @EnableWebSocket! public class WsConfig implements WebSocketConfigurer {! ! ! ! @Override! public void registerWebSocketHandlers(! ! ! ! ! ! ! ! ! ! WebSocketHandlerRegistry registry) {! ! registry.addHandler(new EchoHandler(), “/echo”).withSockJS();! }! }! MessageHandler doesn’t change (SocketJsService delivers the message to the handler regardless of the protocol)
  • 22. Problem • WebSockets are too low level and different from HTTP / REST • We need asynchronous, event-driven, reactive programming style • Mmmm, that sounds familiar: JMS, AMQP… 
 but we still want to stick to the Spring MVC programming model
  • 24. …but we want something like this
  • 25. Solution • Stomp over WebSocket • Some Spring Integration types have been promoted to the core • • • Message, MessageChannel, MessageHandler… @MessageMapping, @SubscribeEvent… New spring-messaging module
  • 26. STOMP
  • 27. STOMP • Simple interoperable protocol for asynchronous messaging • Supported by Apache ActiveMQ, RabbitMQ, HornetQ… • Frames modelled on HTTP var socket = new SockJS('/myapp/echo');! var client = Stomp.over(socket); COMMAND! header1:value1! header2:value2! ! Body^@!
  • 28. Client Frames • SEND a message • SUBSCRIBE / UNSUBSCRIBE from destination • ACK / NACK the reception of a message (optional by default)
  • 29. Server Frames • Convey a MESSAGE from subscription to the client • Send RECEIPT when server has successfully processed a client frame • Send an ERROR if something goes wrong
  • 30. Configuration ! @Configuration! @EnableWebSocketMessageBroker! public class Config implements WebSocketMessageBrokerConfigurer {! ! @Override! public void registerStompEndpoints(StompEndpointRegistry r){! r.addEndpoint("/stomp");! }! ! @Override! public void configureMessageBroker(MessageBrokerConfigurer c){! c.enableSimpleBroker("/topic/");! Subscriptions c.setApplicationDestinationPrefixes("/app");! processed by spring }! ! }! simple broker
  • 31. Sending Messages stomp.js stompClient.send("/app/trade", {}, JSON.stringify(trade)); prefix SEND! destination:/app/trade! content-type:application/json! content-length:47! ! {"action":"Sell","ticker":"DELL","shares":"10"}! supports ant-style patterns @MessageMapping("/trade")! public void executeTrade(Trade trade, Principal principal) {! ! trade.setUsername(principal.getName());! ! this.tradeService.executeTrade(trade);! }
  • 32. Handler Methods • Flexible handler method signatures • @PathVariable, @Header/@Headers, @Payload, Message, Principal • Message converters @Controller! public class ChatController {! ! @MessageMapping("/message")! public void sendMessage(String message, Principal principal) {! // ...! }! }!
  • 33. Handler Methods • Can also return a value ! ! ! Return wrapped in a Message and sent to /topic/message @MessageMapping("/message")! public String sendMessage(String message) {! return message.toUpperCase();! } ! • Or define the destination with @SendTo @MessageMapping("/message")! @SendTo("/topic/spring-room")! public String sendMessage(String message) {! return message.toUpperCase();! }!
  • 34. Intercepting Subscriptions stompClient.subscribe("/app/positions", function(message) {! ...! });! SUBSCRIBE! id:sub-0! destination:/app/positions! @Controller! public class PortfolioController {! ! @SubscribeEvent("/positions")! public List<Position> getPositions(Principal p) {! Portfolio portfolio = ...! return portfolio.getPositions();! }! } sent directly to the client, not going though the message broker
  • 35. User destinations • User specific queues can be used • • • /user/** kind of paths queues with unique id will be created Useful to send user related information or errors client.subscribe("/user/queue/private-messages", function(msg) {! // ...! });! ! client.subscribe("/user/queue/errors", function(msg) {! // ...! });!
  • 36. Sending to user @Controller! public class ChatController {! Will be sent to /user/{username}/queue/message ! @MessageMapping("/message")! @SendToUser! public String sendMessage(String message) {! return message.toUpperCase();! }! ! @MessageExceptionHandler! @SendToUser("/queue/errors")! public String handleException(IllegalStateException ex) {! return ex.getMessage();! }! ! }!
  • 37. SimpMessagingTemplate • Sending messages without handler methods template.convertAndSend("/topic/chat", message;! template.convertAndSendToUser(user, dest, message;
  • 38. Using a Message Broker • Previous configuration used Spring’s simple broker • • • Not suitable for clustering Subset of STOMP A message broker can be plugged-in instead
  • 39. Message Broker Config @Configuration! @EnableWebSocketMessageBroker! public class Config implements WebSocketMessageBrokerConfigurer{! ! @Override! public void configureMessageBroker(MessageBrokerConfigurer c){! c.enableStompBrokerRelay("/queue/", "/topic/");! c.setApplicationDestinationPrefixes("/app");! }! }