Copyright © 2013, Oracle and/or its affiliates. All rights reserved.1
Insert Picture Here
Getting Started with WebSocket and Server-Sent Event in JavaArun GuptaDirector, Developer Advocacy, Red Hatblog.arungupta.me, @arungupta
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.Copyright © 2013, Oracle and/or its affiliates. All rights reserved.2
ProgramAgenda
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.3
Interactive Web Sites
HTTP is half-duplexHTTP is verboseHacks for Server Push
● Polling
● Long Polling
● Comet/Ajax
Complex, Inefficient, Wasteful
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.4
WebSocket to the Rescue
TCP based, bi-directional, full-duplex messagingOriginally proposed as part of HTML5IETF-defined Protocol: RFC 6455
● Handshake
● Data Transfer
W3C defined JavaScript APICandidate Recommendation
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.5
Establish a connection
Client
Handshake Request
Handshake ResponseServer
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.6
Handshake Request
GET /chat HTTP/1.1Host: server.example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==Origin: http://example.comSec-WebSocket-Protocol: chat, superchatSec-WebSocket-Version: 13
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.7
Handshake Response
HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=Sec-WebSocket-Protocol: chat
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.8
ServerClient
Handshake Request
Handshake Response
Connected !
Establishing a Connection
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.9
Peer(server)
Peer(client)
Connected !
open open
close
message
error
messagemessage
message
message
Disconnected
WebSocket Lifecycle
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.10
WebSocket APIwww.w3.org/TR/websockets/
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.11 http://caniuse.com/websockets
Browser Support
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.12
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.13
Java API for WebSocket Features
API for WebSocket Server/Client Endpoints● Annotated (@ServerEndpoint, @ClientEndpoint)
● Programmatic (Endpoint)
● WebSocket opening handshake negotiation
Lifecycle callback handlersPackaging with Java EE applications
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.14
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.15
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.16
@ServerEndpoint Attributes
value Relative URI or URI templatee.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.17
Custom Payloads
@ServerEndpoint( value="/hello", encoders={MyMessage.class}, decoders={MyMessage.class})public class MyEndpoint { . . .}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.18
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.19
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.20
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 parameter0..n String parameters annotated with @PathParamReturn 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.21
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.22
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.23
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.24
https://blogs.oracle.com/arungupta/entry/collaborative_whiteboard_using_websocket_in
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.25
WebSocket Client
@ClientEndpointpublic 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.26
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.27
How to view WebSocket messages ?Capture traffic on loopback
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.28
How to view WebSocket messages ?chrome://net-internals -> Sockets -> View live sockets
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.29
Server-Sent Events
Part of HTML5 SpecificationServer-push notificationsCross-browser JavaScript API: EventSourceMessage callbacksMIME type: text/eventstream
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.30
EventSource APIdev.w3.org/html5/eventsource/
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.31
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.32
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.33
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.34
WebSocket and Server-Sent EventCompeting 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.35
WebSocket and Server-Sent EventCompeting 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
Top Related