--- /dev/null
+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
--- /dev/null
+<!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"> </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