SlideShare ist ein Scribd-Unternehmen logo
1 von 27
Downloaden Sie, um offline zu lesen
GWT Web Socket and 
data serialization 
Michele Ficarra 
Software Engineer at Thales Italy S.p.A
Case study 
With GWT this! 
is easy 
Let's focus on the Browser <-> Server communication
“GWT provides an RPC mechanism based on 
Java Servlets to provide access to server-side 
resources. This mechanism includes generation 
of efficient client-side and server-side code to 
serialize objects across the network using 
deferred binding.” 
From gwtproject.org
GWT RPC
GWT RPC 
• Easy to write, hide all AJAX and serialization 
complexity. ! 
• You can use the same POJO in client and server, 
you need only to implement the serializable 
interface.! 
• But …
Push data from the 
server to browser! 
isn’t so easy…
Possible solutions 
• Polling! 
• HTTP Long Polling (COMET)! 
• Web Socket 
Two RFC can help us to choose
“On today's Internet, the Hypertext Transfer 
Protocol (HTTP) is often used (some would say 
abused) to enable asynchronous, "server-initiated" 
communication from a server to a 
client as well as communication from a client to 
a server.” 
From RFC 6202 - Bidirectional HTTP - April 2011
“The WebSocket protocol consists of an 
opening handshake followed by basic message 
framing, layered over TCP. The goal of this 
technology is to provide a mechanism for 
browser-based applications that need two-way 
communication with servers” 
From RFC 6455 - The WebSocket Protocol - December 2011
• WebSocket seems to be the right choice, but GWT 
doesn’t provide natively a way to use it! 
• On Internet we can find a lots of library that can 
help:! 
• Errai - http://erraiframework.org/! 
• Gwt-ws - https://code.google.com/p/gwt-ws/! 
• …! 
• But this time we want to make our hands “dirty” and 
try to do it by ourself!
Web Socket - Client Side 
var websocket = new WebSocket("ws://locahost:8025/echo"); 
! 
websocket.onopen = function(evt) { 
console.log("WebSocket open"); 
}; 
websocket.onclose = function(evt) { 
console.log("WebSocket close"); 
}; 
websocket.onmessage = function(evt) { 
alart(evt.data); 
}; 
websocket.onerror = function(evt) { 
console.log("WebSocket error"); 
}; 
! 
websocket.send("Hello World!"); 
JAVASCRIPT
Web Socket - Client Side 
For use the previous code with GWT we need to write a JSNI wrapper 
package ws; 
import com.google.gwt.core.client.JavaScriptObject; 
! 
public abstract class WebSocket { 
! 
private JavaScriptObject ws; 
! 
public WebSocket(String url) { 
ws = init(url); 
} 
! 
abstract void onClose(); 
abstract void onError(); 
abstract void onMessage(String msg); 
abstract void onOpen(); 
! 
private native JavaScriptObject init(String url) /*-{ 
. . . 
}-*/; 
! 
native void send(String message) /*-{ 
this.@ws.WebSocket::ws.send(message); 
}-*/; 
} 
JAVA
Web Socket - Client Side 
private native JavaScriptObject init(String url) /*-{ 
var websocket = new WebSocket(url); 
var wrapper = this; 
websocket.onopen = function(evt) { 
wrapper.@ws.WebSocket::onOpen()(); 
}; 
websocket.onclose = function(evt) { 
wrapper.@ws.WebSocket::onClose()(); 
}; 
websocket.onmessage = function(evt) { 
wrapper.@ws.WebSocket::onMessage(Ljava/lang/String;)(evt.data); 
}; 
websocket.onerror = function(evt) { 
wrapper.@ws.WebSocket::onError()(); 
}; 
return websocket; 
}-*/; 
JAVA
Web Socket - Server Side 
• For develop the server side we can use the Java 
API for WebSocket (JSR 356), that is part of the 
Java EE 7 standard! 
• If we want use the JSR 356 without a full JEE 7 
container it’s possibile to embed a WS server like 
Tyrus - https://tyrus.java.net/ 
<dependency> 
<groupId>org.glassfish.tyrus</groupId> 
<artifactId>tyrus-server</artifactId> 
<version>1.8.3</version> 
</dependency> 
<dependency> 
<groupId>org.glassfish.tyrus</groupId> 
<artifactId>tyrus-container-grizzly-server</artifactId> 
<version>1.8.3</version> 
</dependency> 
MAVEN
Web Socket - Server Side 
Example of an Echo Web Socket service with JSR 356 
package ws; 
! 
import javax.websocket.OnMessage; 
import javax.websocket.server.ServerEndpoint; 
! 
@ServerEndpoint("/echo") 
public class EchoEndpoint { 
! 
@OnMessage 
public String echo(String message) { 
return message + " (from your server)"; 
} 
! 
} 
JAVA
Web Socket - Server Side 
Start Tyrus Server in Jetty 6 (DevMode) 
package ws; 
! 
import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 
import javax.websocket.DeploymentException; 
! 
import org.glassfish.tyrus.server.Server; 
! 
public class InitListener implements ServletContextListener { 
! 
private Server server = null; 
! 
@Override 
public void contextDestroyed(ServletContextEvent servletContextEvent) { 
server.stop(); 
} 
! 
@Override 
public void contextInitialized(ServletContextEvent servletContextEvent) { 
try { 
server = new Server("localhost", 8025, "/", null, EchoEndpoint.class); 
server.start(); 
} catch (final DeploymentException e1) { 
e1.printStackTrace(); 
} 
} 
} 
JAVA 
WEB.XML 
<listener> 
<listener-class>ws.InitListener</listener-class> 
</listener>
Data Serialization 
• Now we are capable of send string back and 
forward from the browser to the server and 
viceversa! 
• But if we want use this technology in a complex 
environment this result is a little poor. We want 
send Object not String!! 
• The first idea to fix the problem can be to use JSON 
serialization…
• … and after a little search we found a lots of way to 
do that:! 
• http://www.gwtproject.org/doc/latest/tutorial/JSON.html! 
• https://github.com/nmorel/gwt-jackson! 
• …! 
• But every solution require a lot of boilerplate code 
or adding annotation to the data model! 
• We would like something more similar to the GWT 
RPC, that require only the Serializable interface. 
May be it can be reused?
• After searching in the web and in the GWT source 
code the solution come out! 
• We need to define the interface of an RPC and reuse 
the serialization engine already present in GWT
Data Serialization 
public class Message implements Serializable { 
! 
private String data; 
private String username; 
private Date time; 
! 
/* ... */ 
} 
JAVA 
JAVA 
@RemoteServiceRelativePath("MessageService") 
public interface MessageService extends RemoteService { 
Message getMessage(Message message); 
! 
} 
The RPC Serialization is designed for function call. The 
client serialize the function argument and the server the 
return value. So, if we want exchange the same object, it’s 
important that in the service definition the args and the 
return value are the same class
public String serializeMessae(Message message) { 
try { 
SerializationStreamFactory factory = 
(SerializationStreamFactory) GWT.create(MessageService.class); 
SerializationStreamWriter writer = factory.createStreamWriter(); 
writer.writeObject(message); 
final String data = writer.toString(); 
return data; 
} catch (final SerializationException e) { 
e.printStackTrace(); 
} 
return null; 
} 
JAVA 
Data Serialization - Client Side 
Here there is the trick, the Async Service that is usual 
return by the deferred binding is also an instance of a 
SerializationStreamFactory. That can be used for serialize 
and deserialize objects
public Message deserializeMessae(String data) { 
try { 
SerializationStreamFactory factory = 
(SerializationStreamFactory) GWT.create(MessageService.class); 
final SerializationStreamReader streamReader = factory 
.createStreamReader(data); 
final Message message = (Message) streamReader.readObject(); 
return message; 
} catch (final SerializationException e) { 
e.printStackTrace(); 
} 
return null; 
} 
JAVA 
Data Serialization - Client Side
Data Serialization - Server Side 
private Message deserializeMessage(String data) 
throws SerializationException { 
ServerSerializationStreamReader streamReader = 
new ServerSerializationStreamReader( 
Thread.currentThread().getContextClassLoader(), 
new CustomSerializationPolicyProvider()); 
// Filling stream reader with data 
streamReader.prepareToRead(data); 
// Reading deserialized object from the stream 
final Message message = (Message) streamReader.readObject(); 
return message; 
} 
JAVA 
On server side is more or less the same of the client. We 
need an instance of a ServerSerializationStreamReader for 
read the object. 
The only hack is how create a 
CustomSerializationPolicyProvider
Data Serialization - Serialization Policy 
public class CustomSerializationPolicyProvider 
implements SerializationPolicyProvider { 
! 
@Override 
public SerializationPolicy getSerializationPolicy(String moduleBaseURL, String serializationPolicyStrongName) { 
return new SimpleSerializationPolicy(); 
} 
! 
} 
JAVA 
public class SimpleSerializationPolicy extends SerializationPolicy { 
! 
@Override 
public boolean shouldDeserializeFields(Class<?> clazz) { 
return isSerializable(clazz); 
} 
! 
@Override 
public boolean shouldSerializeFields(Class<?> clazz) { 
return isSerializable(clazz); 
} 
! 
/* ... */ 
! 
private boolean isSerializable(Class<?> clazz) { 
if (clazz != null) { 
if (clazz.isPrimitive() 
|| Serializable.class.isAssignableFrom(clazz) 
|| IsSerializable.class.isAssignableFrom(clazz)) { 
return true; 
} 
} 
return false; 
} 
} 
JAVA 
RPC generates a serialization 
policy file during GWT 
compilation. The serialization 
policy file contains a whitelist 
of allowed types which may be 
serialized.! 
In this simple implementation 
there is only the check of the 
Serializable interface.! 
Watch out of what are you 
serializing or you can perform 
problem on client side.
Data Serialization - Server Side 
private String serializeMessage(final Message messageDto) 
throws SerializationException { 
! 
ServerSerializationStreamWriter serverSerializationStreamWriter = 
new ServerSerializationStreamWriter(new SimpleSerializationPolicy()); 
! 
serverSerializationStreamWriter.writeObject(messageDto); 
String result = serverSerializationStreamWriter.toString(); 
return result; 
} 
JAVA
Data Serialization - OnMessage 
Now we have all pieces for finish the OnMessage method 
@OnMessage 
public void onMessage(String message, Session session) { 
try { 
! 
Message messageDto = deserializeMessage(message); 
! 
String result = serializeMessage(messageDto); 
! 
for (Session s : session.getOpenSessions()) { 
if (s.isOpen()) { 
s.getBasicRemote().sendText(result); 
} 
} 
} catch (final SerializationException | IOException e) { 
logger.log(Level.WARNING, "Error", e); 
} 
} 
JAVA 
Deserialization of an 
incoming message 
from a client 
Serialization for the 
clients. The clients can 
deserialize only object 
encoded by the sever due 
the request - response 
nature of the RPC 
Web Socket 
broadcast
That’s all, happy hacking and thanks for the attention. 
Full working example available on: ! 
https://github.com/michelefi/gwtcon-websocket 
Questions?

Weitere ähnliche Inhalte

Ähnlich wie GWT Web Socket and data serialization

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
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
Tom Croucher
 
Developing RESTful WebServices using Jersey
Developing RESTful WebServices using JerseyDeveloping RESTful WebServices using Jersey
Developing RESTful WebServices using Jersey
b_kathir
 

Ähnlich wie GWT Web Socket and data serialization (20)

AJppt.pptx
AJppt.pptxAJppt.pptx
AJppt.pptx
 
Advance Java Topics (J2EE)
Advance Java Topics (J2EE)Advance Java Topics (J2EE)
Advance Java Topics (J2EE)
 
Servlets
ServletsServlets
Servlets
 
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
 
Web-Socket
Web-SocketWeb-Socket
Web-Socket
 
Getting started with Websocket and Server-sent Events using Java - Arun Gupta
Getting started with Websocket and Server-sent Events using Java - Arun Gupta Getting started with Websocket and Server-sent Events using Java - Arun Gupta
Getting started with Websocket and Server-sent Events using Java - Arun Gupta
 
Getting Started with WebSocket and Server-Sent Events using Java by Arun Gupta
Getting Started with WebSocket and Server-Sent Events using Java by Arun GuptaGetting Started with WebSocket and Server-Sent Events using Java by Arun Gupta
Getting Started with WebSocket and Server-Sent Events using Java by Arun Gupta
 
The HTML5 WebSocket API
The HTML5 WebSocket APIThe HTML5 WebSocket API
The HTML5 WebSocket API
 
Nodejs and WebSockets
Nodejs and WebSocketsNodejs and WebSockets
Nodejs and WebSockets
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 Engine
 
Servlet
ServletServlet
Servlet
 
Groovy & Grails eXchange 2012 vert.x presentation
Groovy & Grails eXchange 2012 vert.x presentationGroovy & Grails eXchange 2012 vert.x presentation
Groovy & Grails eXchange 2012 vert.x presentation
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMS
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Servlet
Servlet Servlet
Servlet
 
Bt0083 server side programing
Bt0083 server side programing Bt0083 server side programing
Bt0083 server side programing
 
SCWCD : Thread safe servlets : CHAP : 8
SCWCD : Thread safe servlets : CHAP : 8SCWCD : Thread safe servlets : CHAP : 8
SCWCD : Thread safe servlets : CHAP : 8
 
Play Framework: async I/O with Java and Scala
Play Framework: async I/O with Java and ScalaPlay Framework: async I/O with Java and Scala
Play Framework: async I/O with Java and Scala
 
Java web application development
Java web application developmentJava web application development
Java web application development
 
Developing RESTful WebServices using Jersey
Developing RESTful WebServices using JerseyDeveloping RESTful WebServices using Jersey
Developing RESTful WebServices using Jersey
 

Mehr von GWTcon

GWTcon 2014 - Apertura
GWTcon 2014 - AperturaGWTcon 2014 - Apertura
GWTcon 2014 - Apertura
GWTcon
 

Mehr von GWTcon (15)

"Jclays, A global solution for application design and automatic GWT code gene...
"Jclays, A global solution for application design and automatic GWT code gene..."Jclays, A global solution for application design and automatic GWT code gene...
"Jclays, A global solution for application design and automatic GWT code gene...
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson
 
In defense of GWT-RPC By Colin Alworth
In defense of GWT-RPC By Colin AlworthIn defense of GWT-RPC By Colin Alworth
In defense of GWT-RPC By Colin Alworth
 
DIY: Split GWT Applications using TURDUCKEN approach By Alberto Mancini
DIY: Split GWT Applications using TURDUCKEN approach By Alberto ManciniDIY: Split GWT Applications using TURDUCKEN approach By Alberto Mancini
DIY: Split GWT Applications using TURDUCKEN approach By Alberto Mancini
 
Unirex Lean tools By Dario Carotenuto
Unirex Lean tools By Dario CarotenutoUnirex Lean tools By Dario Carotenuto
Unirex Lean tools By Dario Carotenuto
 
The future of GWT 2.x - By Colin Alworth
The future of GWT 2.x - By Colin AlworthThe future of GWT 2.x - By Colin Alworth
The future of GWT 2.x - By Colin Alworth
 
Web components with java by Haijian Wang
Web components with java by Haijian WangWeb components with java by Haijian Wang
Web components with java by Haijian Wang
 
UI Framework Development using GWT and HTML Canvas - By Iarosla Kobyliukh
UI Framework Development using GWT and HTML Canvas - By Iarosla KobyliukhUI Framework Development using GWT and HTML Canvas - By Iarosla Kobyliukh
UI Framework Development using GWT and HTML Canvas - By Iarosla Kobyliukh
 
Best Practices - By Lofi Dewanto
Best Practices - By Lofi DewantoBest Practices - By Lofi Dewanto
Best Practices - By Lofi Dewanto
 
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
 
GWT Development for Handheld Devices
GWT Development for Handheld DevicesGWT Development for Handheld Devices
GWT Development for Handheld Devices
 
GWT vs CSS3
GWT vs CSS3GWT vs CSS3
GWT vs CSS3
 
WebTram: una WebApp GWT per l'editing di dati cartografici e topologici di un...
WebTram: una WebApp GWT per l'editing di dati cartografici e topologici di un...WebTram: una WebApp GWT per l'editing di dati cartografici e topologici di un...
WebTram: una WebApp GWT per l'editing di dati cartografici e topologici di un...
 
GWTcon 2014 - Apertura
GWTcon 2014 - AperturaGWTcon 2014 - Apertura
GWTcon 2014 - Apertura
 
GWT videocall: power-up your mobile & web app with WebRTC
GWT videocall:  power-up your mobile & web app with WebRTCGWT videocall:  power-up your mobile & web app with WebRTC
GWT videocall: power-up your mobile & web app with WebRTC
 

Kürzlich hochgeladen

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Kürzlich hochgeladen (20)

[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 

GWT Web Socket and data serialization

  • 1. GWT Web Socket and data serialization Michele Ficarra Software Engineer at Thales Italy S.p.A
  • 2. Case study With GWT this! is easy Let's focus on the Browser <-> Server communication
  • 3. “GWT provides an RPC mechanism based on Java Servlets to provide access to server-side resources. This mechanism includes generation of efficient client-side and server-side code to serialize objects across the network using deferred binding.” From gwtproject.org
  • 5. GWT RPC • Easy to write, hide all AJAX and serialization complexity. ! • You can use the same POJO in client and server, you need only to implement the serializable interface.! • But …
  • 6. Push data from the server to browser! isn’t so easy…
  • 7. Possible solutions • Polling! • HTTP Long Polling (COMET)! • Web Socket Two RFC can help us to choose
  • 8. “On today's Internet, the Hypertext Transfer Protocol (HTTP) is often used (some would say abused) to enable asynchronous, "server-initiated" communication from a server to a client as well as communication from a client to a server.” From RFC 6202 - Bidirectional HTTP - April 2011
  • 9. “The WebSocket protocol consists of an opening handshake followed by basic message framing, layered over TCP. The goal of this technology is to provide a mechanism for browser-based applications that need two-way communication with servers” From RFC 6455 - The WebSocket Protocol - December 2011
  • 10. • WebSocket seems to be the right choice, but GWT doesn’t provide natively a way to use it! • On Internet we can find a lots of library that can help:! • Errai - http://erraiframework.org/! • Gwt-ws - https://code.google.com/p/gwt-ws/! • …! • But this time we want to make our hands “dirty” and try to do it by ourself!
  • 11. Web Socket - Client Side var websocket = new WebSocket("ws://locahost:8025/echo"); ! websocket.onopen = function(evt) { console.log("WebSocket open"); }; websocket.onclose = function(evt) { console.log("WebSocket close"); }; websocket.onmessage = function(evt) { alart(evt.data); }; websocket.onerror = function(evt) { console.log("WebSocket error"); }; ! websocket.send("Hello World!"); JAVASCRIPT
  • 12. Web Socket - Client Side For use the previous code with GWT we need to write a JSNI wrapper package ws; import com.google.gwt.core.client.JavaScriptObject; ! public abstract class WebSocket { ! private JavaScriptObject ws; ! public WebSocket(String url) { ws = init(url); } ! abstract void onClose(); abstract void onError(); abstract void onMessage(String msg); abstract void onOpen(); ! private native JavaScriptObject init(String url) /*-{ . . . }-*/; ! native void send(String message) /*-{ this.@ws.WebSocket::ws.send(message); }-*/; } JAVA
  • 13. Web Socket - Client Side private native JavaScriptObject init(String url) /*-{ var websocket = new WebSocket(url); var wrapper = this; websocket.onopen = function(evt) { wrapper.@ws.WebSocket::onOpen()(); }; websocket.onclose = function(evt) { wrapper.@ws.WebSocket::onClose()(); }; websocket.onmessage = function(evt) { wrapper.@ws.WebSocket::onMessage(Ljava/lang/String;)(evt.data); }; websocket.onerror = function(evt) { wrapper.@ws.WebSocket::onError()(); }; return websocket; }-*/; JAVA
  • 14. Web Socket - Server Side • For develop the server side we can use the Java API for WebSocket (JSR 356), that is part of the Java EE 7 standard! • If we want use the JSR 356 without a full JEE 7 container it’s possibile to embed a WS server like Tyrus - https://tyrus.java.net/ <dependency> <groupId>org.glassfish.tyrus</groupId> <artifactId>tyrus-server</artifactId> <version>1.8.3</version> </dependency> <dependency> <groupId>org.glassfish.tyrus</groupId> <artifactId>tyrus-container-grizzly-server</artifactId> <version>1.8.3</version> </dependency> MAVEN
  • 15. Web Socket - Server Side Example of an Echo Web Socket service with JSR 356 package ws; ! import javax.websocket.OnMessage; import javax.websocket.server.ServerEndpoint; ! @ServerEndpoint("/echo") public class EchoEndpoint { ! @OnMessage public String echo(String message) { return message + " (from your server)"; } ! } JAVA
  • 16. Web Socket - Server Side Start Tyrus Server in Jetty 6 (DevMode) package ws; ! import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.websocket.DeploymentException; ! import org.glassfish.tyrus.server.Server; ! public class InitListener implements ServletContextListener { ! private Server server = null; ! @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { server.stop(); } ! @Override public void contextInitialized(ServletContextEvent servletContextEvent) { try { server = new Server("localhost", 8025, "/", null, EchoEndpoint.class); server.start(); } catch (final DeploymentException e1) { e1.printStackTrace(); } } } JAVA WEB.XML <listener> <listener-class>ws.InitListener</listener-class> </listener>
  • 17. Data Serialization • Now we are capable of send string back and forward from the browser to the server and viceversa! • But if we want use this technology in a complex environment this result is a little poor. We want send Object not String!! • The first idea to fix the problem can be to use JSON serialization…
  • 18. • … and after a little search we found a lots of way to do that:! • http://www.gwtproject.org/doc/latest/tutorial/JSON.html! • https://github.com/nmorel/gwt-jackson! • …! • But every solution require a lot of boilerplate code or adding annotation to the data model! • We would like something more similar to the GWT RPC, that require only the Serializable interface. May be it can be reused?
  • 19. • After searching in the web and in the GWT source code the solution come out! • We need to define the interface of an RPC and reuse the serialization engine already present in GWT
  • 20. Data Serialization public class Message implements Serializable { ! private String data; private String username; private Date time; ! /* ... */ } JAVA JAVA @RemoteServiceRelativePath("MessageService") public interface MessageService extends RemoteService { Message getMessage(Message message); ! } The RPC Serialization is designed for function call. The client serialize the function argument and the server the return value. So, if we want exchange the same object, it’s important that in the service definition the args and the return value are the same class
  • 21. public String serializeMessae(Message message) { try { SerializationStreamFactory factory = (SerializationStreamFactory) GWT.create(MessageService.class); SerializationStreamWriter writer = factory.createStreamWriter(); writer.writeObject(message); final String data = writer.toString(); return data; } catch (final SerializationException e) { e.printStackTrace(); } return null; } JAVA Data Serialization - Client Side Here there is the trick, the Async Service that is usual return by the deferred binding is also an instance of a SerializationStreamFactory. That can be used for serialize and deserialize objects
  • 22. public Message deserializeMessae(String data) { try { SerializationStreamFactory factory = (SerializationStreamFactory) GWT.create(MessageService.class); final SerializationStreamReader streamReader = factory .createStreamReader(data); final Message message = (Message) streamReader.readObject(); return message; } catch (final SerializationException e) { e.printStackTrace(); } return null; } JAVA Data Serialization - Client Side
  • 23. Data Serialization - Server Side private Message deserializeMessage(String data) throws SerializationException { ServerSerializationStreamReader streamReader = new ServerSerializationStreamReader( Thread.currentThread().getContextClassLoader(), new CustomSerializationPolicyProvider()); // Filling stream reader with data streamReader.prepareToRead(data); // Reading deserialized object from the stream final Message message = (Message) streamReader.readObject(); return message; } JAVA On server side is more or less the same of the client. We need an instance of a ServerSerializationStreamReader for read the object. The only hack is how create a CustomSerializationPolicyProvider
  • 24. Data Serialization - Serialization Policy public class CustomSerializationPolicyProvider implements SerializationPolicyProvider { ! @Override public SerializationPolicy getSerializationPolicy(String moduleBaseURL, String serializationPolicyStrongName) { return new SimpleSerializationPolicy(); } ! } JAVA public class SimpleSerializationPolicy extends SerializationPolicy { ! @Override public boolean shouldDeserializeFields(Class<?> clazz) { return isSerializable(clazz); } ! @Override public boolean shouldSerializeFields(Class<?> clazz) { return isSerializable(clazz); } ! /* ... */ ! private boolean isSerializable(Class<?> clazz) { if (clazz != null) { if (clazz.isPrimitive() || Serializable.class.isAssignableFrom(clazz) || IsSerializable.class.isAssignableFrom(clazz)) { return true; } } return false; } } JAVA RPC generates a serialization policy file during GWT compilation. The serialization policy file contains a whitelist of allowed types which may be serialized.! In this simple implementation there is only the check of the Serializable interface.! Watch out of what are you serializing or you can perform problem on client side.
  • 25. Data Serialization - Server Side private String serializeMessage(final Message messageDto) throws SerializationException { ! ServerSerializationStreamWriter serverSerializationStreamWriter = new ServerSerializationStreamWriter(new SimpleSerializationPolicy()); ! serverSerializationStreamWriter.writeObject(messageDto); String result = serverSerializationStreamWriter.toString(); return result; } JAVA
  • 26. Data Serialization - OnMessage Now we have all pieces for finish the OnMessage method @OnMessage public void onMessage(String message, Session session) { try { ! Message messageDto = deserializeMessage(message); ! String result = serializeMessage(messageDto); ! for (Session s : session.getOpenSessions()) { if (s.isOpen()) { s.getBasicRemote().sendText(result); } } } catch (final SerializationException | IOException e) { logger.log(Level.WARNING, "Error", e); } } JAVA Deserialization of an incoming message from a client Serialization for the clients. The clients can deserialize only object encoded by the sever due the request - response nature of the RPC Web Socket broadcast
  • 27. That’s all, happy hacking and thanks for the attention. Full working example available on: ! https://github.com/michelefi/gwtcon-websocket Questions?