Your SlideShare is downloading. ×
Turning the Web on its head - let's have the Server call the Client
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

Turning the Web on its head - let's have the Server call the Client

3,394
views

Published on

We will take the accepted view that a Web-Client calls (via HTTP GET or POST) a server and turn it on its head. Let\'s have the server call the client. It is really not that far fetched, to imaging a …

We will take the accepted view that a Web-Client calls (via HTTP GET or POST) a server and turn it on its head. Let\'s have the server call the client. It is really not that far fetched, to imaging a scenario where the server, when it has determined that something exciting just happened (e.g., the Dow Jones Industrial Avg. Index jumped 100 points) calls the Web Client, instead of clients constantly polling the server (even when the DOW barely moves).


0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,394
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Let’s have the server call the clientLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 2. Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 3. Polling Client Server Did something just happen ? Notify Client Server Something just happened !Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 4. QuoteService Number getQuote(String symbol); Set<String> getCoveredStocks();Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 5. package com.carlsbadcubes.quotes; import java.util.Set; public interface QuoteService { Number getQuote( String symbol ); Set<String> getCoveredStocks(); }Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 6. Exposing the QuoteService: Hessian Binary Web Service ProtocolLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 7. <?xml version="1.0" encoding="UTF-8"?> <web-app> <servlet> defined in hessian.jar <servlet-name>qservice</servlet-name> <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class> <init-param> Implementation <param-name>service-class</param-name> <param-value>com.carlsbadcubes.quotes.QuoteServiceImpl</param-value> </init-param> <init-param> <param-name>api-class</param-name> Interface <param-value>com.carlsbadcubes.quotes.QuoteService</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>qservice</servlet-name> <url-pattern>/service/*</url-pattern> </servlet-mapping> </web-app>Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 8. Hessian Client String url = “http://hostname.domain/service”; ServiceProxyFactory factory = new HessianProxyFactory(); QuoteService qs = (QuoteService) factory.create( QuoteService.class, url );Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 9. Demo Tomcat Server with a Hessian Service and a Hessian based Java ClientLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 10. Tomcat Server Client Jan 18, 2008 11:43:11 AM org.apache.coyote.http11.Http11Protocol init INFO: Initializing Coyote HTTP/1.1 on http-8080 Jan 18, 2008 11:43:11 AM org.apache.catalina.startup.Catalina load INFO: Initialization processed in 1460 ms Jan 18, 2008 11:43:11 AM org.apache.catalina.core.StandardService start INFO: Starting service Catalina Jan 18, 2008 11:43:11 AM org.apache.catalina.core.StandardEngine start INFO: Starting Servlet Engine: Apache Tomcat/6.0.14 Jan 18, 2008 11:43:14 AM org.apache.coyote.http11.Http11Protocol start INFO: Starting Coyote HTTP/1.1 on http-8080 Jan 18, 2008 11:43:14 AM org.apache.jk.common.ChannelSocket init INFO: JK: ajp13 listening on /0.0.0.0:8009 Jan 18, 2008 11:43:14 AM org.apache.jk.server.JkMain start INFO: Jk running ID=0 time=0/105 config=null Jan 18, 2008 11:43:14 AM org.apache.catalina.startup.Catalina start INFO: Server startup in 3046 ms Connected to serverLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 11. Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com daniel.gredler.net
  • 12. Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com daniel.gredler.net
  • 13. When debugging with a TCP-Monitor, use “Bulap” instead of “Hessian.Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 14. Polling Client Server Did something just happen ? Notify Client Server Something just happened !Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 15. JMX supports event-handling over multiple JVMsLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 16. JMX supports event-handling over multiple JVMsLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 17. package com.carlsbadcubes.mbeans; import java.util.Map; Interface name ends in ...MBean public interface SystemInfoMBean { Long getFreeMemory(); /** @return Long, max memory, JVM will attempt to use. */ Long getMaxMemory(); /** @return Long total amount of memory in the JVM. */ Long getTotalMemory(); /** Runs the garbage collector. */ void runGC(); /** @return Map current system properties. */ Map getSystemInfo(); }Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 18. Class implements an interface with the class’ name +”MBean” package com.carlsbadcubes.mbeans; import java.util.Map; /** SystemInfo delegates incoming requests to System or Runtime. */ public class SystemInfo implements SystemInfoMBean { ... /** @return Long, total amount of memory in the JVM. */ public Long getTotalMemory() { return Runtime.getRuntime().totalMemory(); } /** Runs the garbage collector. */ public void runGC() { Runtime.getRuntime().gc(); } /** @return Map, current system properties. */ public Map getSystemInfo() { return System.getProperties(); } }Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 19. JMX supports event-handling over multiple JVMsLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 20. import javax.management.*; // Create an MBeanServer private MBeanServer mbServer = MBeanServerFactory.createMBeanServer( “mydomain” ); // Creating an MBean mbServer.createMBean( SystemInfo.class.getName(), new ObjectName( ":name=SystemInfo,type=system" ) );Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 21. JMX supports event-handling over multiple JVMsLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 22. import javax.management.remote.*; JMXServiceURL jmxurl = new JMXServiceURL( "rmi", "localhost", 9090, "/jndi/rmi://"+InetAddress.getLocalHost().getHostName()+":1099/jmxapp”); JMXConnectorServer connector = ! JMXConnectorServerFactory.newJMXConnectorServer(jmxurl,null,mbServer); connector.start(); Example JMXServiceURL: service:jmx:rmi://localhost:9090/jndi/rmi://wpbook.local:1099/jmxappLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 23. JMX-Demo Server: MBeanServer / JMXConnector(RMI) Client: Java’s JConsoleLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 24. Server ClientLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 25. JMXClient public class JMXClient implements NotificationListener { private MBeanServerConnection mbsc; private ObjectName oname = new ObjectName("com.carlsbadcubes:name=PrimeGenerator,type=custom"); public JMXClient( String serviceUrl ) throws Exception { JMXServiceURL jmxurl = new JMXServiceURL( serviceUrl ); JMXConnector connector = JMXConnectorFactory.connect( jmxurl ); mbsc = connector.getMBeanServerConnection(); mbsc.addNotificationListener( oname, this, null, null ); } ... }Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 26. JMXClient // // Implement NotificationListener Interface // public void handleNotification(Notification note, Object object ) { System.out.println( note.getSequenceNumber() + ". type= " + note.getType() + " msg= " + note.getMessage() + " data= " + note.getUserData() ); }Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 27. MBeanServerConnection mbsc = connector.getMBeanServerConnection(); ObjectName oname = new ObjectName("com.carlsbadcubes:name=SystemInfo,type=custom"); ... mbsc = connector.getMBeanServerConnection(); Long free = (Long) mbsc.getAttribute( oname, "FreeMemory" ); import com.carlsbadcubes.mbeans.SystemInfoMBean; ... MBeanServerConnection mbsc = connector.getMBeanServerConnection(); ObjectName oname = new ObjectName("com.carlsbadcubes:name=SystemInfo,type=custom"); ... mbsc = connector.getMBeanServerConnection(); SystemInfoMBean sysinfo = (SystemInfoMBean)MBeanServerInvocationHandler.newProxyInstance( mbsc, oname, SystemInfoMBean.class, false ); Long free = sysinfo.getFreeMemory();Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 28. JMX-Demo Server: MBeanServer / JMXConnector(RMI) Client: Custom Java Client ApplicationLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 29. JMXConnector JMXConnectorServer RMI JMX JNDI RMI Registry Client Server JMX SocketSvr MBeanServerConnection MBeanServerLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 30. JMXConnector JMXConnectorServer HTTP HessianClient Hessian Invoker Servlet Client Server MBeanServerConnection MBeanServerLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 31. JMX / Hessian Demo Server: MBeanServer / JMXConnector(HESSIAN) Client: Specialized Java ClientLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 32. Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 33. Client Server Did something just happen ? Polling Something happened ! Notify JMX Client What happened ? Server HTTP This happened. HTTPLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 34. AJAX, Comet, and NIOLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 35. Poll Long Poll (AJAX Push)Client Server Client Server Request Request Response Event Response Request Request Responsetime timeLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 36. Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 37. Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 38. <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> blocking & non-blocking IO configuration<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" />Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 39. public class QuoteServlet extends HttpServlet implements CometProcessor, Listener { protected final ArrayList<CometEvent> connections = new ArrayList<CometEvent>(); /** * Process the given Comet event. * @param event The Comet event that will be processed * @throws java.io.IOException * @throws ServletException */ public void event(CometEvent event) throws IOException, ServletException { if (CometEvent.EventType.BEGIN.equals(event.getEventType())) {.. connections.add(event); } else if (CometEvent.EventType.ERROR.equals(event.getEventType())) .. } else if (CometEvent.EventType.END.equals(event.getEventType())) .. } else if (CometEvent.EventType.READ.equals(event.getEventType())) .. } } // Implement Quotes Listener Interface public void notify(String message) { if (message != null) { // JSON-style message containing ticker and value e.g.: { "ticker": AAPL, "value" : 123.45 } messageSender.send("{"ticker":"" + message + "", "value":"" + qservice.getQuote(message) + ""}"); } } /** Sends an X-JSON message in the HTTP Response Header and flushes the response and closes the connection.*/ public class MessageSender implements Runnable { protected final ArrayList<String> messages = new ArrayList<String>(); public void run() { // Send any pending message on all the open connections for (int i = connections.size() - 1; 0 <= i; i--) { CometEvent event = connections.get(i); event.getHttpServletResponse().addHeader("X-JSON", pendingMessages[0]); } // endof run } // endof class MessageSender }Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 40. AJAX / Comet Demo Server: Comet-Style Web Application (non-blocking) Client: Modern Web BrowserLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 41. Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 42. Thanks For Coming!Let’s have the server call the client Copyright © 2009 http://wolfpaulus.com
  • 43. Resources Slides: http://wolfpaulus.com/bio/talks/ahr.pdf Code: http://wolfpaulus.com/bio/talks/ahr.zip Hessian • http://hessian.caucho.com/ • http://wiki.caucho.com/Hessian JMX • http://java.sun.com/products/JavaManagement/best-practices.html • JMX Accelerated Howto by Blaine Simpson http://www.admc.com/blaine/howtos/jmx/ MX4J Remoting • http://mx4j.sourceforge.net/docs/ch03.html Non-Blocking I/O • http://tomcat.apache.org/tomcat-6.0-doc/aio.htmlLet’s have the server call the client Copyright © 2009 http://wolfpaulus.com