SlideShare a Scribd company logo
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.1
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.2
Getting Started with
WebSocket and Server-Sent
Event in Java
Arun Gupta
blogs.oracle.com/arungupta, @arungupta
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.3 Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Insert Information Protection Policy Classification from Slide 16
Program
Agenda
§  WebSocket Primer
§  Getting Started with WebSocket
§  Server-Sent Event Primer
§  Getting Started with Server-Sent Event
§  Resources
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.4
Interactive Web Sites
§  HTTP is half-duplex
§  HTTP is verbose
§  Hacks for Server Push
–  Polling
–  Long Polling
–  Comet/Ajax
§  Complex, Inefficient, Wasteful
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.5
WebSocket to the Rescue
§  TCP based, bi-directional, full-duplex messaging
§  Originally proposed as part of HTML5
§  IETF-defined Protocol: RFC 6455
–  Handshake
–  Data Transfer
§  W3C defined JavaScript API
–  Candidate Recommendation
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.6
Establish a connection
Client
Handshake Request
Handshake Response
Server
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.7
Handshake Request
GET /chat HTTP/1.1

Host: server.example.com

Upgrade: websocket

Connection: Upgrade

Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==

Origin: http://example.com

Sec-WebSocket-Protocol: chat, superchat

Sec-WebSocket-Version: 13 "
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.8
Handshake Response
HTTP/1.1 101 Switching Protocols

Upgrade: websocket

Connection: Upgrade

Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

Sec-WebSocket-Protocol: chat "
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.9
ServerClient
Handshake Request
Handshake Response
Connected !
Establishing a Connection
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.10
Peer
(server)
Peer
(client)
Connected !
open open
close
message
error
message
message
message
message
Disconnected
WebSocket Lifecycle
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.11
WebSocket API
www.w3.org/TR/websockets/
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.12 http://caniuse.com/websockets
Browser Support
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.13
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.14
Java API for WebSocket Features
§  API for WebSocket Server/Client Endpoints
–  Annotated (@ServerEndpoint, @ClientEndpoint)
–  Programmatic (Endpoint)
§  WebSocket opening handshake negotiation
§  Lifecycle callback handlers
§  Packaging with Java EE applications
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.15
Annotated Endpoint
import javax.websocket.*;



@ServerEndpoint("/hello")

public class HelloBean {



@OnMessage

public String sayHello(String name) {

return “Hello “ + name;

}

}"
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.16
Annotations
Annotation Level Purpose
@ServerEndpoint" class Turns a POJO into a WebSocket Endpoint
@ClientEndpoint" class POJO wants to act as client
@OnMessage" method Intercepts WebSocket Message events
@PathParam"
method
parameter
Flags a matched path segment of a URI-template
@OnOpen" method Intercepts WebSocket Open events
@OnClose" method Intercepts WebSocket Close events
@OnError" method Intercepts errors during a conversation
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.17
@ServerEndpoint Attributes
value"
Relative URI or URI template
e.g. /hello or /chat/{subscriber-level}
decoders" list of message decoder classnames
encoders" list of message encoder classnames
subprotocols" list of the names of the supported subprotocols
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.18
Custom Payloads
@ServerEndpoint(

value="/hello",

encoders={MyMessage.class},

decoders={MyMessage.class}

)

public class MyEndpoint {

. . .

}"
"
"
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.19
Custom Payloads – Text
public class MyMessage implements Decoder.Text<MyMessage>, Encoder.Text<MyMessage> {

private JsonObject jsonObject;



public MyMessage decode(String s) {

jsonObject = Json.createReader(new StringReader(s)).readObject();

return this;"
}"
public boolean willDecode(String string) {

return true; // Only if can process the payload

}"
"
public String encode(MyMessage myMessage) {

return myMessage.jsonObject.toString();

}

}"
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.20
Custom Payloads – Binary
public class MyMessage implements Decoder.Binary<MyMessage>, Encoder.Binary<MyMessage> {



public MyMessage decode(byte[] bytes) {

. . .

return this;"
}"
public boolean willDecode(byte[] bytes) {

. . .

return true; // Only if can process the payload

}"
"
public byte[] encode(MyMessage myMessage) {

. . .

}

}"
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.21
Which methods can be @OnMessage ?
§  Exactly one of the following
–  Text: String, Java primitive or equivalent class, String and boolean,
Reader, any type for which there is a decoder
–  Binary: byte[], ByteBuffer, byte[] and boolean, ByteBuffer and
boolean, InptuStream, any type for which there is a decoder
–  Pong messages: PongMessage"
§  An optional Session parameter
§  0..n String parameters annotated with @PathParam"
§  Return type: String, byte[], ByteBuffer, Java primitive or class
equivalent or any type for which there is a encoder
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.22
Sample Messages
§  void m(String s);"
§  void m(Float f, @PathParam(“id”)int id);"
§  Product m(Reader reader, Session s);"
§  void m(byte[] b); or void m(ByteBuffer b);"
§  Book m(int i, Session s, @PathParam(“isbn”)String
isbn, @PathParam(“store”)String store);"
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.23
Chat Server
@ServerEndpoint("/chat")"
public class ChatBean {"
static Set<Session> peers = Collections.synchronizedSet(…);



@OnOpen

public void onOpen(Session peer) {

peers.add(peer);

}



@OnClose

public void onClose(Session peer) {

peers.remove(peer);

}



. . ."
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.24
Chat Server
. . .



@OnMessage"
public void message(String message, Session client) {"
for (Session peer : peers) {

peer.getBasicRemote().sendObject(message);

}

}

}"
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.25
https://blogs.oracle.com/arungupta/entry/collaborative_whiteboard_using_websocket_in
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.26
WebSocket Client
@ClientEndpoint

public class HelloClient {

@OnMessage

public void message(String message, Session session) {

// process message from server

}

}

"
WebSocketContainer c = ContainerProvider.getWebSocketContainer();

c.connectToServer(HelloClient.class, “hello”);"
"
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.27
Programmatic Endpoint
public class MyEndpoint extends Endpoint {



@Override

public void onOpen(Session session) {

session.addMessageHandler(new MessageHandler.Text() {

public void onMessage(String name) {

try {

session.getBasicRemote().sendText(“Hello “ + name);

} catch (IOException ex) {

}

} 

});

}

}"
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.28
How to view WebSocket messages ?
Capture traffic on loopback
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.29
How to view WebSocket messages ?
chrome://net-internals -> Sockets -> View live sockets
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.30
Server-Sent Events
§  Part of HTML5 Specification
§  Server-push notifications
§  Cross-browser JavaScript API: EventSource"
§  Message callbacks
§  MIME type: text/eventstream"
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.31
EventSource API
dev.w3.org/html5/eventsource/
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.32
Server-Sent Events Example
var url = ‘webresources/items/events’;

var source = new EventSource(url);"
source.onmessage = function (event) {

console.log(event.data);

}

source.addEventListener(“size”, function(event) {"
console.log(event.name + ‘ ‘ + event.data);

}"
Client-side
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.33
Server-Sent Events Example
private final SseBroadcaster BROADCASTER = new SseBroadcaster();



@GET

@Path("events”)

@Produces(SseFeature.SERVER_SENT_EVENTS)

public EventOutput fruitEvents() {

final EventOutput eventOutput = new EventOutput();

BROADCASTER.add(eventOutput);

return eventOutput;

}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.34
Server-Sent Events Example
@POST

@Consumes(MediaType.APPLICATION_FORM_URLENCODED)

public void addFruit(@FormParam("fruit")String fruit) {

FRUITS.add(fruit);



// Broadcasting an un-named event with the name of the newly added item in data

BROADCASTER.broadcast(new OutboundEvent.Builder().data(String.class, fruit).build());



// Broadcasting a named "add" event with the current size of the items collection in
data

BROADCASTER.broadcast(new OutboundEvent.Builder().name("size").data(Integer.class,
FRUITS.size()).build());

}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.35
WebSocket and Server-Sent Event
Competing technologies ?
WebSocket Server-Sent Event
Over a custom protocol Over simple HTTP
Full Duplex, Bi-directional Server-Push Only, Client->Server
is out-of-band (higher latency)
Native support in most browsers Can be poly-filled to backport
Not straight forward protocol Simpler protocol
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.36
WebSocket and Server-Sent Event
Competing technologies ?
WebSocket Server-Sent Event
Pre-defined message handlers Arbitrary events
Application-specific Built-in support for re-connection
and event id
Require server and/or proxy
configurations
No server or proxy changes
required
ArrayBuffer and Blob No support for binary types
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.37
Resources
§  Java API for WebSocket
–  Specification: jcp.org/en/jsr/detail?id=356
–  Reference Implementation: java.net/projects/tyrus
–  Integrated in GlassFish Server 4.0
–  Part of Java EE 7
§  Server-Sent Event
–  Integrated in Jersey and GlassFish Server 4.0
–  Not part of Java EE 7
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.38
The preceding material is intended to outline our general product
direction. It is intended for information purposes only, and may not be
incorporated into any contract. It is not a commitment to deliver any
material, code, or functionality, and should not be relied upon in making
purchasing decisions. The development, release, and timing of any
features or functionality described for Oracle’s products remains at the
sole discretion of Oracle.
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.39

More Related Content

Getting Started with WebSocket and Server-Sent Events in Java

  • 1. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.1
  • 2. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.2 Getting Started with WebSocket and Server-Sent Event in Java Arun Gupta blogs.oracle.com/arungupta, @arungupta
  • 3. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.3 Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Insert Information Protection Policy Classification from Slide 16 Program Agenda §  WebSocket Primer §  Getting Started with WebSocket §  Server-Sent Event Primer §  Getting Started with Server-Sent Event §  Resources
  • 4. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.4 Interactive Web Sites §  HTTP is half-duplex §  HTTP is verbose §  Hacks for Server Push –  Polling –  Long Polling –  Comet/Ajax §  Complex, Inefficient, Wasteful
  • 5. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.5 WebSocket to the Rescue §  TCP based, bi-directional, full-duplex messaging §  Originally proposed as part of HTML5 §  IETF-defined Protocol: RFC 6455 –  Handshake –  Data Transfer §  W3C defined JavaScript API –  Candidate Recommendation
  • 6. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.6 Establish a connection Client Handshake Request Handshake Response Server
  • 7. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.7 Handshake Request GET /chat HTTP/1.1
 Host: server.example.com
 Upgrade: websocket
 Connection: Upgrade
 Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
 Origin: http://example.com
 Sec-WebSocket-Protocol: chat, superchat
 Sec-WebSocket-Version: 13 "
  • 8. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.8 Handshake Response HTTP/1.1 101 Switching Protocols
 Upgrade: websocket
 Connection: Upgrade
 Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
 Sec-WebSocket-Protocol: chat "
  • 9. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.9 ServerClient Handshake Request Handshake Response Connected ! Establishing a Connection
  • 10. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.10 Peer (server) Peer (client) Connected ! open open close message error message message message message Disconnected WebSocket Lifecycle
  • 11. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.11 WebSocket API www.w3.org/TR/websockets/
  • 12. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.12 http://caniuse.com/websockets Browser Support
  • 13. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.13
  • 14. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.14 Java API for WebSocket Features §  API for WebSocket Server/Client Endpoints –  Annotated (@ServerEndpoint, @ClientEndpoint) –  Programmatic (Endpoint) §  WebSocket opening handshake negotiation §  Lifecycle callback handlers §  Packaging with Java EE applications
  • 15. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.15 Annotated Endpoint import javax.websocket.*;
 
 @ServerEndpoint("/hello")
 public class HelloBean {
 
 @OnMessage
 public String sayHello(String name) {
 return “Hello “ + name;
 }
 }"
  • 16. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.16 Annotations Annotation Level Purpose @ServerEndpoint" class Turns a POJO into a WebSocket Endpoint @ClientEndpoint" class POJO wants to act as client @OnMessage" method Intercepts WebSocket Message events @PathParam" method parameter Flags a matched path segment of a URI-template @OnOpen" method Intercepts WebSocket Open events @OnClose" method Intercepts WebSocket Close events @OnError" method Intercepts errors during a conversation
  • 17. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.17 @ServerEndpoint Attributes value" Relative URI or URI template e.g. /hello or /chat/{subscriber-level} decoders" list of message decoder classnames encoders" list of message encoder classnames subprotocols" list of the names of the supported subprotocols
  • 18. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.18 Custom Payloads @ServerEndpoint(
 value="/hello",
 encoders={MyMessage.class},
 decoders={MyMessage.class}
 )
 public class MyEndpoint {
 . . .
 }" " "
  • 19. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.19 Custom Payloads – Text public class MyMessage implements Decoder.Text<MyMessage>, Encoder.Text<MyMessage> {
 private JsonObject jsonObject;
 
 public MyMessage decode(String s) {
 jsonObject = Json.createReader(new StringReader(s)).readObject();
 return this;" }" public boolean willDecode(String string) {
 return true; // Only if can process the payload
 }" " public String encode(MyMessage myMessage) {
 return myMessage.jsonObject.toString();
 }
 }"
  • 20. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.20 Custom Payloads – Binary public class MyMessage implements Decoder.Binary<MyMessage>, Encoder.Binary<MyMessage> {
 
 public MyMessage decode(byte[] bytes) {
 . . .
 return this;" }" public boolean willDecode(byte[] bytes) {
 . . .
 return true; // Only if can process the payload
 }" " public byte[] encode(MyMessage myMessage) {
 . . .
 }
 }"
  • 21. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.21 Which methods can be @OnMessage ? §  Exactly one of the following –  Text: String, Java primitive or equivalent class, String and boolean, Reader, any type for which there is a decoder –  Binary: byte[], ByteBuffer, byte[] and boolean, ByteBuffer and boolean, InptuStream, any type for which there is a decoder –  Pong messages: PongMessage" §  An optional Session parameter §  0..n String parameters annotated with @PathParam" §  Return type: String, byte[], ByteBuffer, Java primitive or class equivalent or any type for which there is a encoder
  • 22. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.22 Sample Messages §  void m(String s);" §  void m(Float f, @PathParam(“id”)int id);" §  Product m(Reader reader, Session s);" §  void m(byte[] b); or void m(ByteBuffer b);" §  Book m(int i, Session s, @PathParam(“isbn”)String isbn, @PathParam(“store”)String store);"
  • 23. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.23 Chat Server @ServerEndpoint("/chat")" public class ChatBean {" static Set<Session> peers = Collections.synchronizedSet(…);
 
 @OnOpen
 public void onOpen(Session peer) {
 peers.add(peer);
 }
 
 @OnClose
 public void onClose(Session peer) {
 peers.remove(peer);
 }
 
 . . ."
  • 24. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.24 Chat Server . . .
 
 @OnMessage" public void message(String message, Session client) {" for (Session peer : peers) {
 peer.getBasicRemote().sendObject(message);
 }
 }
 }"
  • 25. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.25 https://blogs.oracle.com/arungupta/entry/collaborative_whiteboard_using_websocket_in
  • 26. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.26 WebSocket Client @ClientEndpoint
 public class HelloClient {
 @OnMessage
 public void message(String message, Session session) {
 // process message from server
 }
 }
 " WebSocketContainer c = ContainerProvider.getWebSocketContainer();
 c.connectToServer(HelloClient.class, “hello”);" "
  • 27. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.27 Programmatic Endpoint public class MyEndpoint extends Endpoint {
 
 @Override
 public void onOpen(Session session) {
 session.addMessageHandler(new MessageHandler.Text() {
 public void onMessage(String name) {
 try {
 session.getBasicRemote().sendText(“Hello “ + name);
 } catch (IOException ex) {
 }
 } 
 });
 }
 }"
  • 28. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.28 How to view WebSocket messages ? Capture traffic on loopback
  • 29. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.29 How to view WebSocket messages ? chrome://net-internals -> Sockets -> View live sockets
  • 30. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.30 Server-Sent Events §  Part of HTML5 Specification §  Server-push notifications §  Cross-browser JavaScript API: EventSource" §  Message callbacks §  MIME type: text/eventstream"
  • 31. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.31 EventSource API dev.w3.org/html5/eventsource/
  • 32. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.32 Server-Sent Events Example var url = ‘webresources/items/events’;
 var source = new EventSource(url);" source.onmessage = function (event) {
 console.log(event.data);
 }
 source.addEventListener(“size”, function(event) {" console.log(event.name + ‘ ‘ + event.data);
 }" Client-side
  • 33. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.33 Server-Sent Events Example private final SseBroadcaster BROADCASTER = new SseBroadcaster();
 
 @GET
 @Path("events”)
 @Produces(SseFeature.SERVER_SENT_EVENTS)
 public EventOutput fruitEvents() {
 final EventOutput eventOutput = new EventOutput();
 BROADCASTER.add(eventOutput);
 return eventOutput;
 }
  • 34. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.34 Server-Sent Events Example @POST
 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
 public void addFruit(@FormParam("fruit")String fruit) {
 FRUITS.add(fruit);
 
 // Broadcasting an un-named event with the name of the newly added item in data
 BROADCASTER.broadcast(new OutboundEvent.Builder().data(String.class, fruit).build());
 
 // Broadcasting a named "add" event with the current size of the items collection in data
 BROADCASTER.broadcast(new OutboundEvent.Builder().name("size").data(Integer.class, FRUITS.size()).build());
 }
  • 35. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.35 WebSocket and Server-Sent Event Competing technologies ? WebSocket Server-Sent Event Over a custom protocol Over simple HTTP Full Duplex, Bi-directional Server-Push Only, Client->Server is out-of-band (higher latency) Native support in most browsers Can be poly-filled to backport Not straight forward protocol Simpler protocol
  • 36. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.36 WebSocket and Server-Sent Event Competing technologies ? WebSocket Server-Sent Event Pre-defined message handlers Arbitrary events Application-specific Built-in support for re-connection and event id Require server and/or proxy configurations No server or proxy changes required ArrayBuffer and Blob No support for binary types
  • 37. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.37 Resources §  Java API for WebSocket –  Specification: jcp.org/en/jsr/detail?id=356 –  Reference Implementation: java.net/projects/tyrus –  Integrated in GlassFish Server 4.0 –  Part of Java EE 7 §  Server-Sent Event –  Integrated in Jersey and GlassFish Server 4.0 –  Not part of Java EE 7
  • 38. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.38 The preceding material is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.
  • 39. Copyright © 2013, Oracle and/or its affiliates. All rights reserved.39