WebSockets in Java
From n00b to pro

22 Dec 2013, JavaDay, Pance Cavkovski
Theory

- WebSocket is a protocol providing full-duplex
communications over a single TCP
connection.
- Standardized by IETF as RFC 6455
- Designed to be implemented in web browsers
and web servers
- HTTP Upgrade request for initiating
connection

* Contents from Wikipedia: http://en.wikipedia.org/wiki/Web_sockets

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
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept:
HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

Netcetera | 2
Sample application

https://github.com/hsilomedus/web-sockets-samples
Netcetera | 3
public static void main(String[] args)
JavaWebSocket (web-socket-samples/javawebsockets)
public class Main extends WebSocketServer {
public Main() {
super(new InetSocketAddress(8887));
}
@Override
public void onOpen(WebSocket conn,
ClientHandshake handshake) {
//Handle new connection here
conn.send(“{”connected”: true}”);
}
@Override
public void onMessage(WebSocket conn,
String message) {
//Handle client received message here
}
* https://github.com/TooTallNate/Java-WebSocket

@Override
public void onClose(WebSocket conn, int code,
String reason, boolean remote) {
//Handle closing connection here
}
@Override
public void onError(WebSocket conn,
Exception exc) {
//Handle error during transport here
}
public static void main(String[] args) {
Main server = new Main();
server.start();
}
}
Netcetera | 4
Client
JavaScript WebSocket API
var socket = new WebSocket(“ws://localhost:8887”);
socket.onopen = function() {
//event handler when the connection has been established
socket.send(nickname);
};
socket.onmessage = function(message) {
//event handler when data has been received from the server
alert(message.data);
};
socket.onclose = function() {
//event handler when the socket has been properly closed
}
socket.onerror = function() {
//event handler when an error has occurred during communication
}
Netcetera | 5
Java EE 7: JSR 356 + Java7
Tomcat (>7.0.43) (web-socket-samples/eesockets)
@ServerEndpoint(“/chat”)
public class EESocketChatEndpoint {
@OnOpen
public void onOpen(Session session) {
//Handle new connection here
session.getBasicRemote()
.sendText(“{”connected”: true}”);
}
@OnMessage
public void onMessage(String message) {
//Handle client received message here
}

@OnClose
public void onClose(Session session,
CloseReason reason) {
//Handle closing connection here
}
@OnError
public void onError(Session session,
Throwable throwable) {
//Handle error during transport here
}
}

* JSR 356, Java API for WebSocket: http://www.oracle.com/technetwork/articles/java/jsr356-1937161.html (javax.websocket.*)

Netcetera | 6
Client
Pretty much the same JavaScript WebSocket API
var socket = new WebSocket(”ws://” + document.domain + “:8080/eesockets/chat”);
socket.onopen = function() {
//event handler when the connection has been established
socket.send(nickname);
};
socket.onmessage = function(message) {
//event handler when data has been received from the server
alert(message.data);
};
socket.onclose = function() {
//event handler when the socket has been properly closed
}
socket.onerror = function() {
//event handler when an error has occurred during communication
}
Netcetera | 7
Spring4
Static dispatcher servlet config
public class DispatcherServletInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer{
@Override
protected Class<?>[] getRootConfigClasses() { return null; }
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] {WebConfig.class};
}
@Override
protected String[] getServletMappings() { return new String[]{“/”}; }
@Override
protected void customizeRegistration(Dynamic registration) {
registration.setInitParameter(“dispatchOptionsRequest”, “true”);
}
}
Netcetera | 8
Spring4
Static context config
@Configuration
@EnableWebMvc
@EnableWebSocket
@ComponentScan(basePackages={“mk.hsilomedus.springsockets.service”})
public class WebConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(chatWenSocketHandler(), “/chat”).withSockJS();
}
@Bean
public WebSocketHandler chatWebSocketHandler() {
return new PerConnectionWebSocketHandler(ChatWebSocketHandler.class);
}
@Override
public void configureDefaultServletHandling(DefaultServerHandlerConfigurer configurer) {
configurer.enable();
}
Netcetera | 9
}
Spring4
WebSocketHandler (web-socket-samples/springsockets)
public class ChatWebSocketHandler extends
TextWebSocketHandler {
@Override
public void afterConnectionEstablished(
WebSocketSession session) {
//Handle new connection here
session.sendMessage(
“{”connected”: true}”);
}
@Override
public void handleTextMessage(
WebSocketSession session,
TextMessage message) {
//Handle message.getPayload() here
}
* http://blog.gopivotal.com/products/websocket-architecture-in-spring-4-0

@Override
public void afterConnectionClosed(
WebSocketSession session,
CloseStatus status) {
//Handle closing connection here
}
@Override
public void handleTransportError(
WebSocketSession session,
Throwable exception) {
//Handle error during transport here
}
}

Netcetera | 10
Client
SockJS
//I can now fallback to longpoll and do IE9!!!
var socket = new SockJS(”http://” + document.domain + “:8080/springsockets/chat”);
socket.onopen = function() {
//event handler when the connection has been established
socket.send(nickname);
};
socket.onmessage = function(message) {
//event handler when data has been received from the server
alert(message.data);
};
socket.onclose = function() {
//event handler when the socket has been properly closed
}
socket.onerror = function() {
//event handler when an error has occurred during communication
}
Netcetera | 11
socket.close();
Thanks for your attention
- The whole source code is available on github:
https://github.com/hsilomedus/web-sockets-samples
- /javawebsockets – with the JavaWebSocket library
- /eesockets – with Tomcat 7.0.47
- /springsockets – with Spring4 RC2 and Tomcat 7.0.47
- All three are eclipse projects running on Java7
- Questions?
- https://twitter.com/hsilomedus, http://hsilomedus.me/
Netcetera | 12

Web sockets in Java

  • 1.
    WebSockets in Java Fromn00b to pro 22 Dec 2013, JavaDay, Pance Cavkovski
  • 2.
    Theory - WebSocket isa protocol providing full-duplex communications over a single TCP connection. - Standardized by IETF as RFC 6455 - Designed to be implemented in web browsers and web servers - HTTP Upgrade request for initiating connection * Contents from Wikipedia: http://en.wikipedia.org/wiki/Web_sockets 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 HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= Sec-WebSocket-Protocol: chat Netcetera | 2
  • 3.
  • 4.
    public static voidmain(String[] args) JavaWebSocket (web-socket-samples/javawebsockets) public class Main extends WebSocketServer { public Main() { super(new InetSocketAddress(8887)); } @Override public void onOpen(WebSocket conn, ClientHandshake handshake) { //Handle new connection here conn.send(“{”connected”: true}”); } @Override public void onMessage(WebSocket conn, String message) { //Handle client received message here } * https://github.com/TooTallNate/Java-WebSocket @Override public void onClose(WebSocket conn, int code, String reason, boolean remote) { //Handle closing connection here } @Override public void onError(WebSocket conn, Exception exc) { //Handle error during transport here } public static void main(String[] args) { Main server = new Main(); server.start(); } } Netcetera | 4
  • 5.
    Client JavaScript WebSocket API varsocket = new WebSocket(“ws://localhost:8887”); socket.onopen = function() { //event handler when the connection has been established socket.send(nickname); }; socket.onmessage = function(message) { //event handler when data has been received from the server alert(message.data); }; socket.onclose = function() { //event handler when the socket has been properly closed } socket.onerror = function() { //event handler when an error has occurred during communication } Netcetera | 5
  • 6.
    Java EE 7:JSR 356 + Java7 Tomcat (>7.0.43) (web-socket-samples/eesockets) @ServerEndpoint(“/chat”) public class EESocketChatEndpoint { @OnOpen public void onOpen(Session session) { //Handle new connection here session.getBasicRemote() .sendText(“{”connected”: true}”); } @OnMessage public void onMessage(String message) { //Handle client received message here } @OnClose public void onClose(Session session, CloseReason reason) { //Handle closing connection here } @OnError public void onError(Session session, Throwable throwable) { //Handle error during transport here } } * JSR 356, Java API for WebSocket: http://www.oracle.com/technetwork/articles/java/jsr356-1937161.html (javax.websocket.*) Netcetera | 6
  • 7.
    Client Pretty much thesame JavaScript WebSocket API var socket = new WebSocket(”ws://” + document.domain + “:8080/eesockets/chat”); socket.onopen = function() { //event handler when the connection has been established socket.send(nickname); }; socket.onmessage = function(message) { //event handler when data has been received from the server alert(message.data); }; socket.onclose = function() { //event handler when the socket has been properly closed } socket.onerror = function() { //event handler when an error has occurred during communication } Netcetera | 7
  • 8.
    Spring4 Static dispatcher servletconfig public class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{ @Override protected Class<?>[] getRootConfigClasses() { return null; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] {WebConfig.class}; } @Override protected String[] getServletMappings() { return new String[]{“/”}; } @Override protected void customizeRegistration(Dynamic registration) { registration.setInitParameter(“dispatchOptionsRequest”, “true”); } } Netcetera | 8
  • 9.
    Spring4 Static context config @Configuration @EnableWebMvc @EnableWebSocket @ComponentScan(basePackages={“mk.hsilomedus.springsockets.service”}) publicclass WebConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer { public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(chatWenSocketHandler(), “/chat”).withSockJS(); } @Bean public WebSocketHandler chatWebSocketHandler() { return new PerConnectionWebSocketHandler(ChatWebSocketHandler.class); } @Override public void configureDefaultServletHandling(DefaultServerHandlerConfigurer configurer) { configurer.enable(); } Netcetera | 9 }
  • 10.
    Spring4 WebSocketHandler (web-socket-samples/springsockets) public classChatWebSocketHandler extends TextWebSocketHandler { @Override public void afterConnectionEstablished( WebSocketSession session) { //Handle new connection here session.sendMessage( “{”connected”: true}”); } @Override public void handleTextMessage( WebSocketSession session, TextMessage message) { //Handle message.getPayload() here } * http://blog.gopivotal.com/products/websocket-architecture-in-spring-4-0 @Override public void afterConnectionClosed( WebSocketSession session, CloseStatus status) { //Handle closing connection here } @Override public void handleTransportError( WebSocketSession session, Throwable exception) { //Handle error during transport here } } Netcetera | 10
  • 11.
    Client SockJS //I can nowfallback to longpoll and do IE9!!! var socket = new SockJS(”http://” + document.domain + “:8080/springsockets/chat”); socket.onopen = function() { //event handler when the connection has been established socket.send(nickname); }; socket.onmessage = function(message) { //event handler when data has been received from the server alert(message.data); }; socket.onclose = function() { //event handler when the socket has been properly closed } socket.onerror = function() { //event handler when an error has occurred during communication } Netcetera | 11
  • 12.
    socket.close(); Thanks for yourattention - The whole source code is available on github: https://github.com/hsilomedus/web-sockets-samples - /javawebsockets – with the JavaWebSocket library - /eesockets – with Tomcat 7.0.47 - /springsockets – with Spring4 RC2 and Tomcat 7.0.47 - All three are eclipse projects running on Java7 - Questions? - https://twitter.com/hsilomedus, http://hsilomedus.me/ Netcetera | 12