SlideShare uma empresa Scribd logo
1 de 40
Baixar para ler 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

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Spring jdbc
Spring jdbcSpring jdbc
Spring jdbc
 
JavaScriptでSQLを唱えたいだけの人生だった
JavaScriptでSQLを唱えたいだけの人生だったJavaScriptでSQLを唱えたいだけの人生だった
JavaScriptでSQLを唱えたいだけの人生だった
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 
Spring boot
Spring bootSpring boot
Spring boot
 
Spring boot
Spring bootSpring boot
Spring boot
 
gRPC: The Story of Microservices at Square
gRPC: The Story of Microservices at SquaregRPC: The Story of Microservices at Square
gRPC: The Story of Microservices at Square
 
CSP Lv.2の話
CSP Lv.2の話CSP Lv.2の話
CSP Lv.2の話
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기
 
Metaspace
MetaspaceMetaspace
Metaspace
 
REST API 설계
REST API 설계REST API 설계
REST API 설계
 
Writing a fast HTTP parser
Writing a fast HTTP parserWriting a fast HTTP parser
Writing a fast HTTP parser
 
サーバーサイド Kotlin のテストフレームワーク事情
サーバーサイド Kotlin のテストフレームワーク事情サーバーサイド Kotlin のテストフレームワーク事情
サーバーサイド Kotlin のテストフレームワーク事情
 
Spring fest2020 spring-security
Spring fest2020 spring-securitySpring fest2020 spring-security
Spring fest2020 spring-security
 
Spring boot
Spring bootSpring boot
Spring boot
 
Handling inline assembly in Clang and LLVM
Handling inline assembly in Clang and LLVMHandling inline assembly in Clang and LLVM
Handling inline assembly in Clang and LLVM
 
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装
 
(알도개) GraalVM – 자바를 넘어선 새로운 시작의 서막
(알도개) GraalVM – 자바를 넘어선 새로운 시작의 서막(알도개) GraalVM – 자바를 넘어선 새로운 시작의 서막
(알도개) GraalVM – 자바를 넘어선 새로운 시작의 서막
 

Destaque

Spring Boot & WebSocket
Spring Boot & WebSocketSpring Boot & WebSocket
Spring Boot & WebSocket
Ming-Ying Wu
 
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
 

Destaque (20)

Spring Boot & WebSocket
Spring Boot & WebSocketSpring Boot & WebSocket
Spring Boot & WebSocket
 
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
 
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
 

Semelhante a 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
 

Semelhante a 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
 

Último

Último (20)

Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
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
 
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...
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
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...
 
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)
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 

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");! }! }