2013 © Trivadis
BASEL BERN LAUSANNE ZÜRICH DÜSSELDORF FRANKFURT A.M. FREIBURG I.BR. HAMBURG MÜNCHEN STUTTGART WIEN
JUG Mün...
2013 © Trivadis
BASEL BERN LAUSANNE ZÜRICH DÜSSELDORF FRANKFURT A.M. FREIBURG I.BR. HAMBURG MÜNCHEN STUTTGART WIEN
Andy Mo...
2013 © Trivadis
AGENDA
1. Motivation
2. Server Sent Events
3. WebSocket (JSR-356)
4. SSE & WebSockets in Enterprise
 Secu...
2013 © Trivadis
Motivation
18.07.2013
JEE to the Max
4
JEE 7
what’s new?
2013 © Trivadis
Motivation
18.07.2013
JEE to the Max
5
state: function() { return state; }, always: function() { deferred....
2013 © Trivadis
Focus
18.07.2013
JEE to the Max
6
Java
2013 © Trivadis
Server Sent Events
18.07.2013
JEE to the Max
7
2013 © Trivadis
Server Sent Events - Overview
• push from server to client
• SSE EventSource API part
of HTML5
• Part of J...
2013 © Trivadis
SSE
DEMO
https://bitbucket.org/amoncsek/jeemax
18.07.2013
JEE to the Max
9
2013 © Trivadis
SSE
18.07.2013
JEE to the Max
10
TimerBean:
write(new Event(«custom»,data));
Handle:
void onEvent(InboundE...
2013 © Trivadis
SSE- ServerSide
• Subscribe an Event Stream
@GET
@Produces(SseFeature.SERVER_SENT_EVENTS)
public EventOutp...
2013 © Trivadis
SSE– ClientSide (Jersey 2 API’s)
• Client API
Client client = ClientBuilder.newClient();
WebTarget webTarg...
2013 © Trivadis
SSE– Best Practice
• Client: EventSource.close() also closes the Server: EventOutput!
• Use SseBroadcaster...
2013 © Trivadis
SSE
Any questions?
18.07.2013
JEE to the Max
14
2013 © Trivadis
WebSocket (JSR-356)
18.07.2013
JEE to the Max
15
2013 © Trivadis
WebSocket - Overview
18.07.2013
JEE to the Max
16
• Full duplex communication in either
direction
• Java A...
2013 © Trivadis
WebSocket(JSR 356) - Overview
18.07.2013
JEE to the Max
17
• Part of Glassfish 4
• Tyrus project:
• refere...
2013 © Trivadis
WebSocket
18.07.2013
JEE to the Max
18
@ServerEndpoint("/bookings") @ClientEndpoint
Session Session
messag...
2013 © Trivadis
WebSocket – ServerEndpoint (by annotation)
18.07.2013
JEE to the Max
19
• Creating Server Endpoints with a...
2013 © Trivadis
WebSocket – ServerEndpoint (programmatic)
18.07.2013
JEE to the Max
20
• Creating Server Endpoints program...
2013 © Trivadis
WebSocket - ServerEndpoint
18.07.2013
JEE to the Max
21
• Configuring a programmatic Endpoint (WebSocket r...
2013 © Trivadis
WebSocket - ClientEndpoint
18.07.2013
JEE to the Max
22
• Creating Client Endpoints with annotation
@Clien...
2013 © Trivadis
WebSocket - ClientEndpoint
18.07.2013
JEE to the Max
• Creating programmatic Client Endpoint
public class ...
2013 © Trivadis
WebSocket - ClientEndpoint
18.07.2013
JEE to the Max
24
• Configure a Client Endpoint
ClientManager client...
2013 © Trivadis
WebSocket Encoder/Decoder
• Native Message-format is:
• Text
• Binary
• Pong (check connection)
• Encoders...
2013 © Trivadis
WebSocket Encoder
public class MEnc implements Encoder.Binary<Message> {
@Override
public ByteBuffer encod...
2013 © Trivadis
WebSocket Decoder
public class MessageDecoder implements Decoder.Binary<Message> {
public Message decode(B...
2013 © Trivadis
WebSocket @PathParam
• Annotate one or more parameters on:
• @OnMessage, @OnError, @OnClose, @OnOpen
@Serv...
2013 © Trivadis
WebSockets – sending messages
• BUT… how to send messages?
• BasicRemote: blocking until message has been ...
2013 © Trivadis
WebSockets – Broadcasting messages
• interaction with other Sessions
• Identify Sessions by ID
• Only Sess...
2013 © Trivadis
Best Practice
• No automatic reconnection:
• Use OnError to reconnect
• Use Session.getUserProperties() to...
2013 © Trivadis
Best Practice
• One handling method per type!:
• Each websocket endpoint may only have one message handlin...
2013 © Trivadis
WebSockets
Any questions?
18.07.2013
JEE to the Max
33
2013 © Trivadis
SSE / WebSockets in Enterprise
SSE / WebSockets in Enterprise
Securtity
18.07.2013
JEE to the Max
34
2013 © Trivadis
Security – Jersey 2 SSE
• Basic authentication - Jersey 2 way:
Client client = ClientBuilder.newBuilder()....
2013 © Trivadis
Security – WebSocket (Tyrus API)
• Initial handshake over HTTP/HTTPS (ws:// | wss://)
• Session.getPrincip...
2013 © Trivadis
Security – WebSocket (Tyrus API)
• Authentication is nevertheless possible (request properties)
c = new Cl...
2013 © Trivadis
Loadbalancing
18.07.2013
JEE to the Max
38
Loadbalancing
2013 © Trivadis
Loadbalancing - SSE
• Works with mod_proxy / mod_jk
• Problem: notification of EventOutput on each Cluster...
2013 © Trivadis
BASEL BERN LAUSANNE ZÜRICH DÜSSELDORF FRANKFURT A.M. FREIBURG I.BR. HAMBURG MÜNCHEN STUTTGART WIEN
18.07.2...
2013 © Trivadis
Failover
18.07.2013
JEE to the Max
41
Failover
2013 © Trivadis
Failover SSE
• On connection drop:
• Error event
• Try to reconnect
• default wait before trying to reconn...
2013 © Trivadis
Failover WebSockets
• No Session replication available in current (Tyrus) version!
• Use @OnError to recon...
2013 © Trivadis
SSE vs. WebSockets
• send/receive data from client
• provide true real-time
updates
• require servers that...
2013 © Trivadis
Conclusion
Is it Enterprise Ready?
SSE – Yes
WebSocket - Nearly
18.07.2013
JEE to the Max
45
2013 © Trivadis
JEE 7 project overview
18.07.2013
JEE to the Max
46
• Client API - using builder pattern
• asynchronous re...
2013 © Trivadis
JEE 7 project overview
18.07.2013
JEE to the Max
47
Example project with MongoDB
replication in Bitbucket ...
2013 © Trivadis
JEE 7 project overview
18.07.2013
JEE to the Max
48
@Resource(lookup = "jms/connectionFactory")
Connection...
2013 © Trivadis
JEE 7 project overview
18.07.2013
JEE to the Max
49
@Resource(name = "concurrent/myExecutor")
ManagedExecu...
2013 © Trivadis
BASEL BERN LAUSANNE ZÜRICH DÜSSELDORF FRANKFURT A.M. FREIBURG I.BR. HAMBURG MÜNCHEN STUTTGART WIEN
VIELEN ...
2013 © Trivadis
Appendix
1. Wallpaper: http://bensow.deviantart.com/art/Wallpaper-Under-Construction-
252593627
2. http://...
Upcoming SlideShare
Loading in...5
×

Scalableenterpriseapplicationswith jee7andbeyond

424

Published on

Published in: Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
424
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
8
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • Alle Beispiele und Tests mit GlassFish 4 promotionbuilds
  • Einordnung: Technologien mit denen man Daten vom Server zum Client übeträgt; Longpolling GET…Wait,Wait… Work; GET; SSE nur initiales GET, WebSocket: nur Handshake über HTTP
  • SSE keine eigeneSpz. Sondern in JAX-RS angesiedelt; Implementierung als Teil von Jersey 2
  • Repo: JEE 7 maven Projekt mit aktuell 3 Subprojekten; SSE,WebSocket, NoSQL Demo; Ziel: bis zum final aktuell halten als Anlaufpunkt für JEE 7 / GlassFish Tests
  • List items are corresponding to header declaration in HTTP request.public Map&lt;String, List&lt;String&gt;&gt; getHeaders() /** * Returns the header value corresponding to the name.public String getHeader(String name) { final List&lt;String&gt; stringList = headers.get(name); return stringList == null ? null : stringList.get(0); }
  • Beispiel Backoffice Systeme: mehrer Nutzer bearbeiten einkommende Aufträge… mit beiden Techn. Möglich… neue Aufträge werden per broadcast an alle gesendet, bearbeiter sperrt Auftrag und beareitet ihn  statusänderung an alle
  • Scalableenterpriseapplicationswith jee7andbeyond

    1. 1. 2013 © Trivadis BASEL BERN LAUSANNE ZÜRICH DÜSSELDORF FRANKFURT A.M. FREIBURG I.BR. HAMBURG MÜNCHEN STUTTGART WIEN JUG Münster Scalable enterprise applications with JEE7 and beyond Andy Moncsek 17. April 2013 18.07.2013 JEE to the Max 1
    2. 2. 2013 © Trivadis BASEL BERN LAUSANNE ZÜRICH DÜSSELDORF FRANKFURT A.M. FREIBURG I.BR. HAMBURG MÜNCHEN STUTTGART WIEN Andy Moncsek Consultant for Application Devlopment (Zürich) Trainer for JavaEE Assembly & Deployment Contacts: Andy.Moncsek@Trivadis.com Twitter: @AndyAHCP
    3. 3. 2013 © Trivadis AGENDA 1. Motivation 2. Server Sent Events 3. WebSocket (JSR-356) 4. SSE & WebSockets in Enterprise  Security  Loadbalancing / Failover 5. (short) JEE 7 project overview 18.07.2013 JEE to the Max 3
    4. 4. 2013 © Trivadis Motivation 18.07.2013 JEE to the Max 4 JEE 7 what’s new?
    5. 5. 2013 © Trivadis Motivation 18.07.2013 JEE to the Max 5 state: function() { return state; }, always: function() { deferred.done( arguments ).fail( arguments ); return this; }, then: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; return jQuery.Deferred(function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { var action = tuple[ 0 ], fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; // deferred[ done | fail | progress ] for forwarding actions to newDefer deferred[ tuple[1] ](function() { var returned = fn && fn.apply( this, arguments ); if ( returned && jQuery.isFunction( returned.promise ) ) { returned.promise() .done( newDefer.resolve ) .fail( newDefer.reject ) .progress( newDefer.notify ); } else { newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); } }); }); fns = null; }).promise(); },
    6. 6. 2013 © Trivadis Focus 18.07.2013 JEE to the Max 6 Java
    7. 7. 2013 © Trivadis Server Sent Events 18.07.2013 JEE to the Max 7
    8. 8. 2013 © Trivadis Server Sent Events - Overview • push from server to client • SSE EventSource API part of HTML5 • Part of Jersey 2 API’s (JAX-RS) • JMS – Topic(Light)? 18.07.2013 JEE to the Max 8
    9. 9. 2013 © Trivadis SSE DEMO https://bitbucket.org/amoncsek/jeemax 18.07.2013 JEE to the Max 9
    10. 10. 2013 © Trivadis SSE 18.07.2013 JEE to the Max 10 TimerBean: write(new Event(«custom»,data)); Handle: void onEvent(InboundEvent e) @Path(«myEventStream») Subscibe once: new EventSource(http://.../myEventStream)
    11. 11. 2013 © Trivadis SSE- ServerSide • Subscribe an Event Stream @GET @Produces(SseFeature.SERVER_SENT_EVENTS) public EventOutput getEventStream() { return new EventOutput(); } • Put Message to EventOutput EventOutput.write( new OutboundEvent("custom-message“, message)) 18.07.2013 JEE to the Max 11
    12. 12. 2013 © Trivadis SSE– ClientSide (Jersey 2 API’s) • Client API Client client = ClientBuilder.newClient(); WebTarget webTarget = client.target(TARGET_URI); • EventSource API new EventSource(webTarget) { public void onEvent(InboundEvent event) {…} } 18.07.2013 JEE to the Max 12
    13. 13. 2013 © Trivadis SSE– Best Practice • Client: EventSource.close() also closes the Server: EventOutput! • Use SseBroadcaster to broadcast messages to EventOutput • Register: SseBroadcaster.add(EventOutput) • Broadcast: SseBroadcaster.broadcast(OutboundEvent) • Use Server: OutboundEvent.name(«myMessage») to filter messages (like JMS message-property/selector) • Client: InboundEvent.getName().equals(«myMessage») 18.07.2013 JEE to the Max 13
    14. 14. 2013 © Trivadis SSE Any questions? 18.07.2013 JEE to the Max 14
    15. 15. 2013 © Trivadis WebSocket (JSR-356) 18.07.2013 JEE to the Max 15
    16. 16. 2013 © Trivadis WebSocket - Overview 18.07.2013 JEE to the Max 16 • Full duplex communication in either direction • Java API for Server- and Client-Side (JEE7) • Programmatic and annotation-based endpoints • Support for Encoder/Decoder to map message to Java objects • Support for @PathParam
    17. 17. 2013 © Trivadis WebSocket(JSR 356) - Overview 18.07.2013 JEE to the Max 17 • Part of Glassfish 4 • Tyrus project: • reference implementation for JSR 356 WebSocket API for Java • http://java.net/projects/tyrus
    18. 18. 2013 © Trivadis WebSocket 18.07.2013 JEE to the Max 18 @ServerEndpoint("/bookings") @ClientEndpoint Session Session messages Connect
    19. 19. 2013 © Trivadis WebSocket – ServerEndpoint (by annotation) 18.07.2013 JEE to the Max 19 • Creating Server Endpoints with annotation @ServerEndpoint("/bookings") public class BookingEndpoint { @OnOpen public void init(Session s) {} @OnClose … @OnError … @OnMessage public void handleMessage(Message m, Session s) {} }
    20. 20. 2013 © Trivadis WebSocket – ServerEndpoint (programmatic) 18.07.2013 JEE to the Max 20 • Creating Server Endpoints programmatic public class BookingEndpoint extends Endpoint { @Override public void onOpen(Session s, EndpointConfig ec) { s.addMessageHandler(new MessageHandler() { @Override public void onMessage(String text) {…} }); } }
    21. 21. 2013 © Trivadis WebSocket - ServerEndpoint 18.07.2013 JEE to the Max 21 • Configuring a programmatic Endpoint (WebSocket runtime scans the WAR) public class WSAppConfig implements ServerApplicationConfig { public Set<ServerEndpointConfig> getEndpointConfigs(Set set) { add(ServerEndpointConfig.Builder .create(BookingEndpoint.class, "/bookings") .build()); } }
    22. 22. 2013 © Trivadis WebSocket - ClientEndpoint 18.07.2013 JEE to the Max 22 • Creating Client Endpoints with annotation @ClientEndpoint public class Booking { @OnOpen … @OnClose … @OnError … @OnMessage … }
    23. 23. 2013 © Trivadis WebSocket - ClientEndpoint 18.07.2013 JEE to the Max • Creating programmatic Client Endpoint public class Booking extends Endpoint { @Override public void onOpen(Session s, EndpointConfig c) { s.addMessageHandler(…); } } 23
    24. 24. 2013 © Trivadis WebSocket - ClientEndpoint 18.07.2013 JEE to the Max 24 • Configure a Client Endpoint ClientManager client = ClientManager.createClient(); ClientEndpointConfig config = ClientEndpointConfig.Builder.create(); client.connectToServer(new Booking(),config URI.create(“ws://host/bookings“)); Or client.connectToServer(Booking.class,config URI.create(“ws://host/bookings“));
    25. 25. 2013 © Trivadis WebSocket Encoder/Decoder • Native Message-format is: • Text • Binary • Pong (check connection) • Encoders: • Encode message from Java Object to Binary / Text • Decoders • Decode message from Binary / Text to Java Object 18.07.2013 JEE to the Max 25
    26. 26. 2013 © Trivadis WebSocket Encoder public class MEnc implements Encoder.Binary<Message> { @Override public ByteBuffer encode(Message m) throws EncodeException { return ByteBuffer.wrap(SerializationUtils.serialize(message)); } } Register Encoders Client: @ClientEndpoint(encoders = {Menc.class, Menc2.class}) Server: @ServerEndpoint(encoders = {Menc.class, Menc2.class}) 18.07.2013 JEE to the Max 26
    27. 27. 2013 © Trivadis WebSocket Decoder public class MessageDecoder implements Decoder.Binary<Message> { public Message decode(ByteBuffer b) throws DecodeException { return (Message) SerializationUtils.deserialize(b.array()); } public boolean willDecode(ByteBuffer b) { return true } } Register Decoders Client: @ClientEndpoint(decoders = {MessageDecoder.class, Dec.class}) Server: @ServerEndpoint(decoders = {MessageDecoder.class, Dec.class}) 18.07.2013 JEE to the Max 27
    28. 28. 2013 © Trivadis WebSocket @PathParam • Annotate one or more parameters on: • @OnMessage, @OnError, @OnClose, @OnOpen @ServerEndpoint("/bookings/{id}") public class BookingEndpoint { @OnMessage public void handle(@PathParam(“id”) String id, Message m, Session s) {} } 18.07.2013 JEE to the Max 28
    29. 29. 2013 © Trivadis WebSockets – sending messages • BUT… how to send messages? • BasicRemote: blocking until message has been transmitted • session.getBasicRemote().sendObject(message); • AsyncRemote: fire and forget • Future<Void> v = session.getAsyncRemote().sendObject(message); • Progress may be tracked using the Future Object 18.07.2013 JEE to the Max 29
    30. 30. 2013 © Trivadis WebSockets – Broadcasting messages • interaction with other Sessions • Identify Sessions by ID • Only Sessions in same Endpoint are accessible • Sessions only accessible trough Session: • session.getOpenSessions() 18.07.2013 JEE to the Max 30
    31. 31. 2013 © Trivadis Best Practice • No automatic reconnection: • Use OnError to reconnect • Use Session.getUserProperties() to store additional informations • Server Endpoitns have full support for CDI and @Inject • Endpoint can be @Singleton / @Stateless… but requirement was removed from spec! 18.07.2013 JEE to the Max 31
    32. 32. 2013 © Trivadis Best Practice • One handling method per type!: • Each websocket endpoint may only have one message handling method for each of the native websocket message formats. • Solution: inherence, Enums,… 18.07.2013 JEE to the Max 32 @OnMessage public void onAddUser(AddUser user) { } @OnMessage public void onMessage(Message m) { } @OnMessage public void onChatMessage(Message chatMessage) { switch (chatMessage.getType()){ case MESSAGE: break; case ADD_USER: break; } }
    33. 33. 2013 © Trivadis WebSockets Any questions? 18.07.2013 JEE to the Max 33
    34. 34. 2013 © Trivadis SSE / WebSockets in Enterprise SSE / WebSockets in Enterprise Securtity 18.07.2013 JEE to the Max 34
    35. 35. 2013 © Trivadis Security – Jersey 2 SSE • Basic authentication - Jersey 2 way: Client client = ClientBuilder.newBuilder().build(); WebTarget webTarget = client.target(restURL); webTarget.register(new HttpBasicAuthFilter(user, pwd)); • Easy SSL konfigurations SslConfigurator sslConfig = SslConfigurator.newInstance() .keyStoreFile("keystore.jks") .keyPassword("asdfgh") .scurityProtocol("SSL"); 18.07.2013 JEE to the Max 35
    36. 36. 2013 © Trivadis Security – WebSocket (Tyrus API) • Initial handshake over HTTP/HTTPS (ws:// | wss://) • Session.getPrincipal() available BUT…. NO Client API for authentication! 18.07.2013 JEE to the Max 36
    37. 37. 2013 © Trivadis Security – WebSocket (Tyrus API) • Authentication is nevertheless possible (request properties) c = new ClientEndpointConfig.Configurator() { public void beforeRequest(Map<String, List<String>> headers) { headers.put("Authorization", Arrays.asList("Basic " + BASE64Enc.encode(encPwd)))); } }; config = ClientEndpointConfig.Builder. create(). configurator(c).build(); client.connectToServer(CEndpoint.class, config, “ws://…/endpoint"); 18.07.2013 JEE to the Max 37
    38. 38. 2013 © Trivadis Loadbalancing 18.07.2013 JEE to the Max 38 Loadbalancing
    39. 39. 2013 © Trivadis Loadbalancing - SSE • Works with mod_proxy / mod_jk • Problem: notification of EventOutput on each Cluster-Node (Broadcast) • Workaround: bypass the LB and notify the nodes • Duplicate messages to other nodes • Use JMS to notify all nodes in cluster 18.07.2013 JEE to the Max 39
    40. 40. 2013 © Trivadis BASEL BERN LAUSANNE ZÜRICH DÜSSELDORF FRANKFURT A.M. FREIBURG I.BR. HAMBURG MÜNCHEN STUTTGART WIEN 18.07.2013 JEE to the Max ‹#›
    41. 41. 2013 © Trivadis Failover 18.07.2013 JEE to the Max 41 Failover
    42. 42. 2013 © Trivadis Failover SSE • On connection drop: • Error event • Try to reconnect • default wait before trying to reconnect is 3 seconds 18.07.2013 JEE to the Max 42
    43. 43. 2013 © Trivadis Failover WebSockets • No Session replication available in current (Tyrus) version! • Use @OnError to reconnect on failure • Do NOT use properties on Session • Problem: message broadcasting • Set LB weight 100 to one Node • Ensure that all sessions on one Node • Duplicate messages to other nodes 18.07.2013 JEE to the Max 43
    44. 44. 2013 © Trivadis SSE vs. WebSockets • send/receive data from client • provide true real-time updates • require servers that understand the protocol • Can identify peers (by ID) 18.07.2013 JEE to the Max 44 • push data to client • can be configured to provide close to real-time • sent over traditional HTTP, so no modification is required • Can identify events (by ID) WebSocket Server-Sent Events
    45. 45. 2013 © Trivadis Conclusion Is it Enterprise Ready? SSE – Yes WebSocket - Nearly 18.07.2013 JEE to the Max 45
    46. 46. 2013 © Trivadis JEE 7 project overview 18.07.2013 JEE to the Max 46 • Client API - using builder pattern • asynchronous request processing Future<String> future = client.target("http://...").pathParam("", "") .request("text/plain").async().get(..); [4]
    47. 47. 2013 © Trivadis JEE 7 project overview 18.07.2013 JEE to the Max 47 Example project with MongoDB replication in Bitbucket (see Demos) [4]
    48. 48. 2013 © Trivadis JEE 7 project overview 18.07.2013 JEE to the Max 48 @Resource(lookup = "jms/connectionFactory") ConnectionFactory connectionFactory; @Resource(lookup="jms/inboundQueue") Queue inboundQueue; public void sendMessageNew (String payload) { try (JMSContext context = connectionFactory.createContext();) { context.send(inboundQueue,payload); } } [4]
    49. 49. 2013 © Trivadis JEE 7 project overview 18.07.2013 JEE to the Max 49 @Resource(name = "concurrent/myExecutor") ManagedExecutorService executor; executor.execute(new MyRunnableTask(2)); [4]
    50. 50. 2013 © Trivadis BASEL BERN LAUSANNE ZÜRICH DÜSSELDORF FRANKFURT A.M. FREIBURG I.BR. HAMBURG MÜNCHEN STUTTGART WIEN VIELEN DANK. Andy Moncsek Andy.Moncsek@Trivadis.com www.trivadis.com 18.07.2013 JEE to the Max 50
    51. 51. 2013 © Trivadis Appendix 1. Wallpaper: http://bensow.deviantart.com/art/Wallpaper-Under-Construction- 252593627 2. http://de.slideshare.net/MasoudKalali/server-sent-events-async-servlet-web- sockets-and-json-born-to-work-together 3. Tyrus Project: http://java.net/projects/tyrus 4. Jersey 2: http://jersey.java.net/jersey20.html 5. JacpFX: https://code.google.com/p/jacp/ 6. GlassFish 4 downloads: http://glassfish.java.net/public/downloadsindex.html 7. [3] http://blog.exceliance.fr/2012/11/07/websockets-load-balancing-with- haproxy/ 8. [4] http://de.slideshare.net/arungupta1/the-java-ee-7-platform-productivity- html5-16124993 9. http://download.oracle.com/otndocs/jcp/websocket-1_0-pfd-spec/index.html 18.07.2013 JEE to the Max 51
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×