building java html5/websocket applications with jsr 356 · html5/websocket applications with jsr...
TRANSCRIPT
Building Java HTML5/WebSocket Applications with JSR 356
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public2
Program Agenda
WebSocket Primer
JSR 356: Java API for WebSocket
Demo
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public3
Interactive Web Sites
HTTP is half-duplex
Flavors of Server Push
– Polling
– Long Polling
– Comet/Ajax
Complex, Inefficient, Wasteful
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public4
WebSocket to the Rescue
TCP based, bi-directional, full-duplex messaging
Originally proposed as part of HTML5
IETF-defined Protocol: RFC 6455
W3C defined JavaScript API
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public5
What’s the basic idea ?
Establish connection (Single TCP connection)
Send messages in both direction (Bi-directional)
Send message independent of each other (Full Duplex)
End connection
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public6
Establish a connection
Client
Handshake Request
Handshake Response
Server
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public7
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 © 2012, Oracle and/or its affiliates. All rights reserved. Public8
Handshake Response
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public9
Establishing a Connection
ServerClient
Handshake Request
Handshake Response
Connected !
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public10
WebSocket Lifecycle
ServerClient
Connected !
open open
close
message
message
error
messagemessage
Disconnected
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public11
WebSocket API
www.w3.org/TR/websockets/
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public12
Java-WebSocket Kaazing WebSocket Gateway
Grizzly WebSocket SDK
Apache Tomcat 7 Webbit
GlassFish Atmosphere
Autobahn websockets4j
WeberKnecht GNU WebSocket4J
Jetty Netty
JBoss TorqueBox
Caucho Resin SwaggerSocket
jWebSocket jWamp
Java WebSocket Implementations
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public13
Browser Support
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public14
JSR 356: Java API for Web Socket
Specification
– http://jcp.org/en/jsr/detail?id=356
– http://java.net/projects/websocket-spec
– Included in Java EE 7
Reference Implementation
– http://java.net/projects/tyrus
– Bundled with Glassfish 4
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public15
Java API for WebSocket Features
Create WebSocket Endpoints
– Interface-driven (Endpoint)
– Annotation-driven (@ServerEndpoint)
Client and server APIs
SPI for extensions and data frames
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public16
Basic API Tour
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public17
Hello World Server
public class HelloServer extends Endpoint {
@Override
public void onOpen(Session session,
EndpointConfig configuration) {
session.addMessageHandler(
new MessageHandler.Whole<String>() {
public void onMessage(String name) {
try {
session.getBasicRemote().sendText(“Hello “ + name);
} catch (IOException ioe) {
// Handle failure.
}
}
});
}
}
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public18
Hello World Client
public class HelloClient extends Endpoint {
@Override
public void onOpen(Session session,
EndpointConfig configuration) {
try {
session.getBasicRemote().sendText("Hello you!");
} catch (IOException ioe) {
. . .
}
}
}
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public19
Client Server Configuration
ServerContainer serverContainer =
(ServerContainer) servletContext.getAttribute(
“javax.websocket.server.ServerContainer”);
ServerEndpointConfig serverConfiguration =
ServerEndpointConfig.Builder.create(
HelloServer.class, "/hello").build();
serverContainer.addEndpoint(serverConfiguration);
...
URI clientURI = new URI("ws://myserver.com/websockets/hello");
WebSocketContainer container =
ContainerProvider.getWebSocketContainer();
ClientEndpointConfig clientConfiguration =
ClientEndpointConfig.Builder.create().build();
container.connectToServer(HelloClient.class,
clientConfiguration, clientURI);
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public20
Main API Classes: javax.websocket.*
Endpoint: Intercepts WebSocket lifecycle events
MessageHandler: Handles all incoming messages for an Endpoint
RemoteEndpoint: Represents the ‘other end’ of this conversation
Session: Represents the active conversation
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public21
Object Model
WebS
ocket
End
po
int
Client
Client
Client
Remote
Endpoint
Remote
Endpoint
Remote
Endpoint
Session
Message
Handler
Session
Message
Handler
Session
Message
Handler
Internet
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public22
Sending the Message
Whole string *RemoteEndpoint.Bas
icsendText(String message)
Binary data *RemoteEndpoint.Bas
icsendBinary(ByteBuffer message)
String fragmentsRemoteEndpoint.Bas
icsendText(String part, boolean last)
Binary data fragmentsRemoteEndpoint.Bas
ic
sendBinary(ByteBuffer part, boolean
last)
Blocking stream of textRemoteEndpoint.Bas
icWriter getSendWriter())
Blocking stream of binary
data
RemoteEndpoint.Bas
icOutputStream getSendStream()
Custom objectRemoteEndpoint.Bas
icsendObject(Object customObject)
* additional flavors: by completion, by future
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public23
Receiving the Message
Whole string MessageHandler.Whole<String> onMessage(String message)
Binary dataMessageHandler.Whole<ByteBuf
fer>onMessage(ByteBuffer message)
String fragmentsMessageHandler.Partial<Strin
g>
onMessage(String part, boolean
last)
Binary data fragmentsMessageHandler.Partial<ByteB
uffer>
onMessage(ByteBuffer part,
boolean last)
Blocking stream of text MessageHandler.Whole<Reader> onMessage(Reader r)
Blocking stream of
binary data
MessageHandler.Whole<InputSt
eam>onMessage(InputStream r)
Custom object of type T MessageHandler.Whole<T> onMessage(T customObject)
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public24
POJO + Annotations
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public25
Hello World Annotations
@ServerEndpoint("/hello")
public class HelloBean {
@OnMessage
public String sayHello(String name) {
return “Hello “ + name;
}
}
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public26
WebSocket Annotations
Annotation Level Purpose
@ServerEndpoint class Turns a POJO into a WebSocket Server Endpoint
@ClientEndpoint class Turns a POJO into a WebSocket Client Endpoint
@OnOpen method Intercepts WebSocket Open events
@OnClose method Intercepts WebSocket Close events
@OnMessage method Intercepts WebSocket Message events
@PathParammethod
parameterFlags a matched path segment of a URI-template
@OnError method Intercepts errors during a conversation
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public27
@ServerEndpoint attributes
valueRelative URI or URI template
e.g. “/hello” or “/chat/{subscriber-level}”
configurator Custom configuration
decoders list of message decoder classnames
encoders list of message encoder classnames
subprotocols list of the names of the supported subprotocols
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public28
Custom Payloads
@ServerEndpoint(
value="/hello",
encoders={MyMessage.class},
decoders={MyMessage.class}
)
public class MyEndpoint {
. . .
}
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public29
Custom Payloads – Text
public class MyMessage
implements Decoder.Text<MyMessage>, Encoder.Text<MyMessage> {
private JsonObject jsonObject;
public MyMessage decode(String s) {
jsonObject = new 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 © 2012, Oracle and/or its affiliates. All rights reserved. Public30
Custom Payloads – Binary
public class MyMessage
implements Decoder.Binary<MyMessage>, Encoder.Binary<MyMessage> {
public MyMessage decode(ByteBuffer bytes) {
. . .
return this;
}
public boolean willDecode(ByteBuffer bytes) {
. . .
return true; // Only if can process the payload
}
public ByteBuffer encode(MyMessage myMessage) {
. . .
}
}
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public31
Chat Sample
@ServerEndpoint("/chat")
public class ChatBean {
Set<Session> peers = Collections.synchronizedSet(…);
@OnOpen
public void onOpen(Session peer) {
peers.add(peer);
}
@OnClose
public void onClose(Session peer) {
peers.remove(peer);
}
...
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public32
Chat Sample (Continued)
. . .
@OnMessage
public void message(String message, Session client) {
for (Session peer : peers) {
peer.getBasicRemote().sendObject(message);
}
}
}
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public33
URI Template Matching
@ServerEndpoint(“/orders/{order-id}”)
public class MyEndpoint {
@OnMessage
public void processOrder(
@PathParam(“order-id”) String orderId) {
...
}
}
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public34
@OnMessage Methods
A parameter type that can be decoded in incoming message
– String, primitive, Reader, ByteBuffer, byte[], InputStream, or
any type for which there is a decoder
An optional Session parameter
Boolean partial flag
0..n String parameters annotated with @PathParameter
A return type that can be encoded in outgoing message
– String, primitive, Reader, ByteBuffer, byte[], InputStream, or any type for
which there is an encoder
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public35
Java WebSocket Hello World Demo
https://github.com/m-reza-rahman/hello-websocket
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public36
Try it Out!
http://download.java.net/glassfish/4.0/release/glassfish-4.0.zip
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public37
Resources
Specification
– JSR: jcp.org/en/jsr/detail?id=356
– Mailing Lists, JIRA, Archive: java.net/projects/websocket-spec
Reference Implementation
– Tyrus: java.net/projects/tyrus
– GlassFish: http://glassfish.org