work on the bayeux samples
authorfhanik <fhanik@13f79535-47bb-0310-9956-ffa450edef68>
Tue, 21 Oct 2008 18:07:04 +0000 (18:07 +0000)
committerfhanik <fhanik@13f79535-47bb-0310-9956-ffa450edef68>
Tue, 21 Oct 2008 18:07:04 +0000 (18:07 +0000)
git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@706696 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/tomcat/bayeux/BayeuxServlet.java
java/org/apache/tomcat/bayeux/ClientImpl.java
java/org/apache/tomcat/bayeux/RequestBase.java
test/org/apache/cometd/bayeux/samples/BayeuxStockTicker.java [new file with mode: 0644]
test/org/apache/cometd/bayeux/samples/EchoChatClient.java
webapps/cometd/WEB-INF/web.xml
webapps/cometd/examples/simplechat/ticker.html [new file with mode: 0644]
webapps/cometd/index.html

index c230336..837086d 100644 (file)
@@ -92,7 +92,7 @@ public class BayeuxServlet implements CometProcessor {
     \r
     protected int getReconnectInterval() {\r
         String rs = servletConfig.getInitParameter("reconnectInterval");\r
-        int rct = 5000; //5 seconds\r
+        int rct = 1000; //1 seconds\r
         try {\r
             rct = Integer.parseInt(rs);\r
         }catch (NumberFormatException nfe) {\r
index f1ab929..894f9ef 100644 (file)
@@ -115,9 +115,10 @@ public class ClientImpl implements Client {
             //local clients must have a listener\r
             ArrayList<Message> list = new ArrayList<Message>();\r
             for (int i=0; msgs!=null && i<msgs.length; i++) {\r
+                //dont deliver to ourselves\r
                 if (this!=msgs[i].getClient()) list.add(msgs[i]);\r
             }\r
-            if (getListener() != null) {\r
+            if (getListener() != null && list.size()>0) {\r
                 getListener().deliver(list.toArray(new Message[0]));\r
             }\r
         } else {\r
index 6e1fc6a..e3c4000 100644 (file)
@@ -76,7 +76,7 @@ public abstract class RequestBase implements BayeuxRequest {
     \r
     protected static Log log = LogFactory.getLog(RequestBase.class);\r
     \r
-    protected int reconnectInterval;\r
+    protected int reconnectInterval = 1000;\r
     \r
     protected RequestBase(TomcatBayeux tb, CometEvent event, JSONObject jsReq) throws JSONException {\r
         this.tomcatBayeux = tb;\r
diff --git a/test/org/apache/cometd/bayeux/samples/BayeuxStockTicker.java b/test/org/apache/cometd/bayeux/samples/BayeuxStockTicker.java
new file mode 100644 (file)
index 0000000..5f61d29
--- /dev/null
@@ -0,0 +1,215 @@
+package org.apache.cometd.bayeux.samples;\r
+\r
+import javax.servlet.ServletContextEvent;\r
+import javax.servlet.ServletContextListener;\r
+import javax.servlet.ServletContextAttributeListener;\r
+import javax.servlet.ServletContextAttributeEvent;\r
+import org.apache.cometd.bayeux.Bayeux;\r
+\r
+import java.text.DecimalFormat;\r
+import java.util.List;\r
+import java.util.Random;\r
+import java.util.concurrent.atomic.AtomicInteger;\r
+import org.apache.cometd.bayeux.Client;\r
+import org.apache.cometd.bayeux.Listener;\r
+import org.apache.cometd.bayeux.Message;\r
+import org.apache.cometd.bayeux.Channel;\r
+\r
+public class BayeuxStockTicker implements ServletContextListener,\r
+        ServletContextAttributeListener, Listener {\r
+\r
+    static AtomicInteger counter = new AtomicInteger(0);\r
+    protected int id;\r
+    protected Bayeux b;\r
+    protected Client c;\r
+    protected boolean alive = true;\r
+    protected boolean initialized = false;\r
+    protected TickerThread tt = new TickerThread();\r
+\r
+    public BayeuxStockTicker() {\r
+        id = counter.incrementAndGet();\r
+        System.out.println("new listener created with id:" + id);\r
+    }\r
+\r
+    public void contextDestroyed(ServletContextEvent servletContextEvent) {\r
+        alive = false;\r
+        tt.run = false;\r
+        tt.interrupt();\r
+    }\r
+\r
+    public void contextInitialized(ServletContextEvent servletContextEvent) {\r
+    }\r
+\r
+    public void attributeAdded(ServletContextAttributeEvent scae) {\r
+        if (scae.getName().equals(Bayeux.DOJOX_COMETD_BAYEUX)) {\r
+            if (initialized) return;\r
+            initialized = true;\r
+            System.out.println("Starting stock ticker server client!");\r
+            b = (Bayeux) scae.getValue();\r
+            c = b.newClient("stock-ticker-", this);\r
+            tt.start();\r
+        }\r
+    }\r
+\r
+    public void attributeRemoved(ServletContextAttributeEvent scae) {\r
+        if (scae.getName().equals(Bayeux.DOJOX_COMETD_BAYEUX)) {\r
+            initialized = false;\r
+            b = (Bayeux) scae.getValue();\r
+            List<Channel> chs = b.getChannels();\r
+            for (Channel ch : chs) {\r
+                ch.unsubscribe(c);\r
+            }\r
+        }\r
+    }\r
+\r
+    public void attributeReplaced(\r
+            ServletContextAttributeEvent servletContextAttributeEvent) {\r
+    }\r
+\r
+    public void removed(boolean timeout) {\r
+        System.out.println("Client removed.");\r
+    }\r
+\r
+    public void deliver(Message[] msgs) {\r
+        for (int i = 0; msgs != null && i < msgs.length; i++) {\r
+            Message msg = msgs[i];\r
+            System.out.println("[stock ticker server client ]received message:" + msg);\r
+        }\r
+    }\r
+\r
+    public class TickerThread extends Thread {\r
+        public boolean run = true;\r
+\r
+        public TickerThread() {\r
+            setName("Ticker Thread");\r
+        }\r
+\r
+        public void run() {\r
+            try {\r
+                \r
+                Stock[] stocks = new Stock[] { \r
+                        new Stock("GOOG", 435.43),\r
+                        new Stock("YHOO", 27.88), \r
+                        new Stock("SPRG", 1015.55), };\r
+                for (Stock s : stocks) {\r
+                    Channel ch = b.getChannel("/stock/"+s.getSymbol(), true);\r
+                    ch.subscribe(c);\r
+                    \r
+                }\r
+                Random r = new Random(System.currentTimeMillis());\r
+                while (run) {\r
+                    for (int j = 0; j < 1; j++) {\r
+                        int i = r.nextInt() % 3;\r
+                        if (i < 0)\r
+                            i = i * (-1);\r
+                        Stock stock = stocks[i];\r
+                        double change = r.nextDouble();\r
+                        boolean plus = r.nextBoolean();\r
+                        if (plus) {\r
+                            stock.setValue(stock.getValue() + change);\r
+                        } else {\r
+                            stock.setValue(stock.getValue() - change);\r
+                        }\r
+                        Channel ch = b.getChannel("/stock/"+stock.getSymbol(), true);\r
+                        Message m = b.newMessage(c);\r
+                        m.put("stock", stock.toString());\r
+                        m.put("symbol", stock.getSymbol());\r
+                        m.put("price", stock.getValueAsString());\r
+                        m.put("change", stock.getLastChangeAsString());\r
+                        ch.publish(m);\r
+                        System.out.println("Stock: "+stock.getSymbol()+" Price: "+stock.getValueAsString()+" Change: "+stock.getLastChangeAsString());\r
+                    }\r
+                    Thread.sleep(850);\r
+                }\r
+            } catch (InterruptedException ix) {\r
+\r
+            } catch (Exception x) {\r
+                x.printStackTrace();\r
+            }\r
+        }\r
+    }\r
+\r
+    public static class Stock {\r
+        protected static DecimalFormat df = new DecimalFormat("0.00");\r
+        protected String symbol = "";\r
+        protected double value = 0.0d;\r
+        protected double lastchange = 0.0d;\r
+        protected int cnt = 0;\r
+\r
+        public Stock(String symbol, double initvalue) {\r
+            this.symbol = symbol;\r
+            this.value = initvalue;\r
+        }\r
+\r
+        public void setCnt(int c) {\r
+            this.cnt = c;\r
+        }\r
+\r
+        public int getCnt() {\r
+            return cnt;\r
+        }\r
+\r
+        public String getSymbol() {\r
+            return symbol;\r
+        }\r
+\r
+        public double getValue() {\r
+            return value;\r
+        }\r
+\r
+        public void setValue(double value) {\r
+            double old = this.value;\r
+            this.value = value;\r
+            this.lastchange = value - old;\r
+        }\r
+\r
+        public String getValueAsString() {\r
+            return df.format(value);\r
+        }\r
+\r
+        public double getLastChange() {\r
+            return this.lastchange;\r
+        }\r
+\r
+        public void setLastChange(double lastchange) {\r
+            this.lastchange = lastchange;\r
+        }\r
+\r
+        public String getLastChangeAsString() {\r
+            return df.format(lastchange);\r
+        }\r
+\r
+        public int hashCode() {\r
+            return symbol.hashCode();\r
+        }\r
+\r
+        public boolean equals(Object other) {\r
+            if (other instanceof Stock) {\r
+                return this.symbol.equals(((Stock) other).symbol);\r
+            } else {\r
+                return false;\r
+            }\r
+        }\r
+        \r
+        public String toString(){\r
+            StringBuffer buf = new StringBuffer("STOCK#");\r
+            buf.append(getSymbol());\r
+            buf.append("#");\r
+            buf.append(getValueAsString());\r
+            buf.append("#");\r
+            buf.append(getLastChangeAsString());\r
+            buf.append("#");\r
+            buf.append(String.valueOf(getCnt()));\r
+            return buf.toString();\r
+         \r
+        }\r
+\r
+        public Object clone() {\r
+            Stock s = new Stock(this.getSymbol(), this.getValue());\r
+            s.setLastChange(this.getLastChange());\r
+            s.setCnt(this.cnt);\r
+            return s;\r
+        }\r
+    }\r
+\r
+}
\ No newline at end of file
index 3d7c393..6f6ca8e 100644 (file)
@@ -19,33 +19,23 @@ public class EchoChatClient implements ServletContextListener, ServletContextAtt
     protected Client c;\r
     protected boolean alive = true;\r
     protected TimestampThread tt = new TimestampThread();\r
+\r
     public EchoChatClient() {\r
         id = counter.incrementAndGet();\r
         System.out.println("new listener created with id:"+id);\r
     }\r
 \r
-    /**\r
-     * contextDestroyed\r
-     *\r
-     * @param servletContextEvent ServletContextEvent\r
-     * @todo Implement this javax.servlet.ServletContextListener method\r
-     */\r
     public void contextDestroyed(ServletContextEvent servletContextEvent) {\r
         alive = false;\r
         tt.interrupt();\r
     }\r
 \r
-    /**\r
-     * contextInitialized\r
-     *\r
-     * @param servletContextEvent ServletContextEvent\r
-     * @todo Implement this javax.servlet.ServletContextListener method\r
-     */\r
     public void contextInitialized(ServletContextEvent servletContextEvent) {\r
     }\r
 \r
     public void attributeAdded(ServletContextAttributeEvent scae) {\r
         if (scae.getName().equals(Bayeux.DOJOX_COMETD_BAYEUX)) {\r
+            System.out.println("Starting echo chat client!");\r
             b = (Bayeux)scae.getValue();\r
             c = b.newClient("echochat-",this);\r
             Channel ch = b.getChannel("/chat/demo",true);\r
@@ -101,7 +91,7 @@ public class EchoChatClient implements ServletContextListener, ServletContextAtt
                     m.put("join",false);\r
                     ch.publish(m);\r
                 }catch (InterruptedException ignore) {\r
-                    \r
+                    Thread.currentThread().interrupted();\r
                 }catch (Exception x) {\r
                     x.printStackTrace();\r
                 }\r
index 085353b..e8d2f80 100644 (file)
       <param-name>timeout</param-name>\r
       <param-value>120000000</param-value>\r
     </init-param>\r
+    <init-param>\r
+      <param-name>reconnectInterval</param-name>\r
+      <param-value>250</param-value>\r
+    </init-param>\r
     <load-on-startup>1</load-on-startup>\r
   </servlet>\r
 \r
     <url-pattern>/cometd/*</url-pattern>\r
   </servlet-mapping>\r
   \r
+  <listener>\r
+    <listener-class>org.apache.cometd.bayeux.samples.EchoChatClient</listener-class>\r
+  </listener>\r
+  <listener>\r
+    <listener-class>org.apache.cometd.bayeux.samples.BayeuxStockTicker</listener-class>\r
+  </listener>\r
+  \r
 </web-app>\r
 \r
 \r
diff --git a/webapps/cometd/examples/simplechat/ticker.html b/webapps/cometd/examples/simplechat/ticker.html
new file mode 100644 (file)
index 0000000..235b6e4
--- /dev/null
@@ -0,0 +1,129 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
+<html>\r
+<head>\r
+<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1" >\r
+<title>Bayeux Stock Ticker</title>\r
+<script type="text/javascript" src="../../dojo/dojo.js.uncompressed.js"></script>\r
+<script type="text/javascript" src="../../dojox/cometd.js"></script>\r
+<script type="text/javascript" src="../../dojox/cometd/_base.js"></script>\r
+<script type="text/javascript">\r
+\r
+dojo.require("dojox.cometd");\r
+\r
+dojo.addOnUnload(function() {\r
+         dojox.cometd.init("/cometd/cometd");\r
+         dojox.cometd.startBatch();\r
+         dojox.cometd.unsubscribe("/stock/GOOG", this,"");\r
+         dojox.cometd.unsubscribe("/stock/YHOO", this,"");\r
+         dojox.cometd.unsubscribe("/stock/SPRG", this,"");\r
+         dojox.cometd.endBatch();\r
+       });\r
+\r
+\r
+dojo.addOnLoad(function() {\r
+  dojox.cometd.init("/cometd/cometd");\r
+  dojox.cometd.startBatch();\r
+  dojox.cometd.subscribe("/stock/GOOG", onMsgEvent);\r
+  dojox.cometd.subscribe("/stock/YHOO", onMsgEvent);\r
+  dojox.cometd.subscribe("/stock/SPRG", onMsgEvent);\r
+  dojox.cometd.endBatch();\r
+});\r
+\r
+\r
+function trim(str) {\r
+    return str.replace(/(^\s+|\s+$)/g,'');\r
+}\r
+\r
+\r
+function clear() {\r
+  dojo.byId("msgtext").value = "";\r
+  dojo.byId("msgtext").focus();\r
+}\r
+\r
+\r
+function enterKeyHandler(e) {\r
+if (!e) e = window.event;\r
+   if (e.keyCode == 13) {\r
+      send(trim(dojo.byId("msgtext").value));\r
+      clear();\r
+   }\r
+\r
+}\r
+\r
+function subscribe(box, symbol) {\r
+       if (box.checked) {\r
+               dojox.cometd.subscribe("/stock/"+symbol, onMsgEvent);\r
+       } else {\r
+               dojox.cometd.unsubscribe("/stock/"+symbol, onMsgEvent);\r
+       }\r
+}\r
+\r
+function removeChildrenFromNode(node)\r
+{\r
+   if(node == undefined || node == null)\r
+   {\r
+      return;\r
+   }\r
+\r
+   var len = node.childNodes.length;\r
+\r
+       while (node.hasChildNodes())\r
+       {\r
+         node.removeChild(node.firstChild);\r
+       }\r
+}\r
+\r
+function onMsgEvent(event) {\r
+   // Break apart the text string into screen name and message parts.\r
+   var symbol = event.data.symbol;\r
+   var price = event.data.price;\r
+   var pricechange = event.data.change;\r
+   //alert("symbol: "+symbol+" price: "+price+" change: "+pricechange);\r
+\r
+   var pricenode = dojo.byId("price."+symbol);\r
+   var changenode = dojo.byId("change."+symbol);\r
+   removeChildrenFromNode(pricenode);\r
+   removeChildrenFromNode(changenode);\r
+   var pricelabel = document.createTextNode(price);\r
+   pricelabel.value = price;\r
+   var changelabel = document.createTextNode(pricechange);\r
+   changelabel.value = pricechange;\r
+   pricenode.appendChild(pricelabel);\r
+   changenode.appendChild(changelabel);\r
+}\r
+\r
+\r
+</script>\r
+</head>\r
+<body bgcolor="#ffffff">\r
+<h1 align="center">Bayeux Stock Ticker</h1>\r
+<h2 align="left"> &nbsp;</h2>\r
+<p>\r
+<table cellspacing="0" cellpadding="3" width="100%" align="center" border="0">\r
+  <tr>\r
+    <td>SYMBOL</td>\r
+    <td>PRICE</td>\r
+    <td>LAST CHANGE</td>\r
+    <td>SUBSCRIBE</td></tr>\r
+  <tr>\r
+    <td>SPRG</td>\r
+    <td id="price.SPRG"></td>\r
+    <td id="change.SPRG"></td>\r
+    <td id="check.SPRG"><input type="checkbox" id="check.SPRG" checked></td>\r
+  </tr>\r
+  <tr>\r
+    <td>GOOG</td>\r
+    <td id="price.GOOG"></td>\r
+    <td id="change.GOOG"></td>\r
+    <td id="check.GOOG"><input type="checkbox" id="check.GOOG" checked></td>\r
+  </tr>\r
+  <tr>\r
+    <td>YHOO</td>\r
+    <td id="price.YHOO"></td>\r
+    <td id="change.YHOO"></td>\r
+    <td id="check.YHOO"><input type="checkbox" id="check.GOOG" checked></td>\r
+  </tr>\r
+</table>\r
+</p>\r
+</body>\r
+</html>
\ No newline at end of file
index 86f29cd..9a7d6d7 100644 (file)
@@ -3,4 +3,5 @@
 \r
 <p>\r
 Try the <a href="examples/simplechat/cometdchat.htm">Simple Chat Demo</a>.</br>\r
+Try the <a href="examples/simplechat/ticker.html">Stock Ticker Demo</a>.</br>\r
 </p>\r