前言:
有很多类似股票、外汇、期货等实时行情这种应用,客户端需要显示行情牌价等信息。
目前的作法是:客户端定时向服务器请求,无论数据是否有更新,都把数据发到客户端。
我们这里讲的一种技术不同以上这个做法,我们是采用服务器向客户端推的这种方式,该方式的好处不言自明。blazeds中有一个名为:StreamingAMFChannel 的通道,我们就是采用它来实现向客户端推这个功能。
环境准备:
我采用eclipse(wtp)+ flex3 build 的软件环境。软件安装我这里就不说明了。blazeds我采用的是blazeds_bin_3-0-0-544,其实你只要下载blazeds.war文件即可。
操作步骤:
1 、切换至flex development视图模式下,点右键新建一个Flex Project。
如我的项目名为:flex-blazeds
点击Next按纽,来到下一页面,
在这步中,直接点:Finish即可。
接下来,右键点击flex-blazeds项目,打开“属性”对话框,如下图:把红色圈起来的地方,改成红字部分。
点“OK”。
接下来,再新建一名为:cn.bestwiz.design.tc.servlet 的包,再切换至“j2ee视图”,在该视图模式下,新建一名为“TickCacheServlet.java”的Servlet.
点击“Finish”完成即可。
下一步加入flex配置文件。
flex的配置文件默认有四个,文件目录在WebContent/WEB-INF/flex目录下。
messaging-config.xml
proxy-config.xml
remoting-config.xml
services-config.xml
其实,这中间用的是一个,就是services-config.xml,只是在services-config.xml中,包含其它三个。
在services-config.xml文件中,加入如下:
messaging-config.xml文件中,加入如下:
再切换至flex 开发视图,新建一名为:Tick.as的ActionScript文件。
点击“Finish”按纽。
OK,至此,我们的代码全部结束了。
下面我们开始测试。
打开一个浏览器,在浏览器的地址栏中,输入:
http://localhost:8080/flex-blazeds/TickCacheServlet?cmd=start
再返回eclipse,在main.mxml文件上,单击右键,用Flex Application运行它。
之后,在打开的浏览器flash上,点击“Button”按纽,可以看到按纽之前的一个Label的Text一直有数字在增大。
有很多类似股票、外汇、期货等实时行情这种应用,客户端需要显示行情牌价等信息。
目前的作法是:客户端定时向服务器请求,无论数据是否有更新,都把数据发到客户端。
我们这里讲的一种技术不同以上这个做法,我们是采用服务器向客户端推的这种方式,该方式的好处不言自明。blazeds中有一个名为:StreamingAMFChannel 的通道,我们就是采用它来实现向客户端推这个功能。
环境准备:
我采用eclipse(wtp)+ flex3 build 的软件环境。软件安装我这里就不说明了。blazeds我采用的是blazeds_bin_3-0-0-544,其实你只要下载blazeds.war文件即可。
操作步骤:
1 、切换至flex development视图模式下,点右键新建一个Flex Project。
如我的项目名为:flex-blazeds


接下来,右键点击flex-blazeds项目,打开“属性”对话框,如下图:把红色圈起来的地方,改成红字部分。

切换至“java开发视图”,新建名为:cn.bestwiz.design.tc 的包,在该包中,新建名为Tick.java的类,内容如下:
- package cn.bestwiz.design.tc;
- import java.math.BigDecimal;
- import java.util.Date;
- public class Tick {
- private BigDecimal askPrice;
- private BigDecimal bidPrice;
- private BigDecimal midPrice;
- private Date tickTime;
- private String seqno;
- public String getSeqno() {
- return seqno;
- }
- public void setSeqno(String seqno) {
- this.seqno = seqno;
- }
- public BigDecimal getAskPrice() {
- return askPrice;
- }
- public void setAskPrice(BigDecimal askPrice) {
- this.askPrice = askPrice;
- }
- public BigDecimal getBidPrice() {
- return bidPrice;
- }
- public void setBidPrice(BigDecimal bidPrice) {
- this.bidPrice = bidPrice;
- }
- public BigDecimal getMidPrice() {
- return midPrice;
- }
- public void setMidPrice(BigDecimal midPrice) {
- this.midPrice = midPrice;
- }
- public Date getTickTime() {
- return tickTime;
- }
- public void setTickTime(Date tickTime) {
- this.tickTime = tickTime;
- }
- }

点击“Finish”完成即可。
- package cn.bestwiz.design.tc.servlet;
- import java.io.IOException;
- import java.math.BigDecimal;
- import java.util.Date;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import cn.bestwiz.design.tc.Tick;
- import flex.messaging.MessageBroker;
- import flex.messaging.messages.AsyncMessage;
- import flex.messaging.util.UUIDUtils;
- public class TickCacheServlet extends HttpServlet {
- private static FeedThread thread;
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- String cmd = req.getParameter("cmd");
- if (cmd.equals("start")) {
- start();
- }
- if (cmd.equals("stop")) {
- stop();
- }
- }
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- // TODO Auto-generated method stub
- super.doGet(req, resp);
- }
- @Override
- public void destroy() {
- // TODO Auto-generated method stub
- super.destroy();
- }
- @Override
- public void init() throws ServletException {
- // TODO Auto-generated method stub
- super.init();
- }
- public void start() {
- if (thread == null) {
- thread = new FeedThread();
- thread.start();
- }
- System.out.println("start!!");
- }
- public void stop() {
- thread.running = false;
- thread = null;
- }
- public static class FeedThread extends Thread {
- public boolean running = true;
- public void run() {
- MessageBroker msgBroker = MessageBroker.getMessageBroker(null);
- String clientID = UUIDUtils.createUUID();
- int i = 0;
- while (running) {
- Tick tick = new Tick();
- tick.setAskPrice(new BigDecimal("100"));
- tick.setBidPrice(new BigDecimal("100"));
- tick.setMidPrice(new BigDecimal("100"));
- tick.setTickTime(new Date());
- tick.setSeqno(String.valueOf(i));
- System.out.println(i);
- AsyncMessage msg = new AsyncMessage();
- msg.setDestination("tick-data-feed");
- msg.setHeader("DSSubtopic", "tick");
- msg.setClientId(clientID);
- msg.setMessageId(UUIDUtils.createUUID());
- msg.setTimestamp(System.currentTimeMillis());
- msg.setBody(tick);
- msgBroker.routeMessageToService(msg, null);
- i++;
- try {
- Thread.sleep(20);
- } catch (InterruptedException e) {
- }
- }
- }
- }
- }
flex的配置文件默认有四个,文件目录在WebContent/WEB-INF/flex目录下。
messaging-config.xml
proxy-config.xml
remoting-config.xml
services-config.xml
其实,这中间用的是一个,就是services-config.xml,只是在services-config.xml中,包含其它三个。
在services-config.xml文件中,加入如下:
- <channel-definition id="my-streaming-amf" class="mx.messaging.channels.StreamingAMFChannel">
- <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/streamingamf" class="flex.messaging.endpoints.StreamingAMFEndpoint"/>
- <properties>
- <idle-timeout-minutes>0</idle-timeout-minutes>
- <max-streaming-clients>10</max-streaming-clients>
- <server-to-client-heartbeat-millis>5000</server-to-client-heartbeat-millis>
- <user-agent-settings>
- <user-agent match-on="MSIE" kickstart-bytes="2048" max-streaming-connections-per-session="1"/>
- <user-agent match-on="Firefox" kickstart-bytes="2048" max-streaming-connections-per-session="1"/>
- </user-agent-settings>
- </properties>
- </channel-definition>
- <destination id="tick-data-feed">
- <properties>
- <server>
- <allow-subtopics>true</allow-subtopics>
- <subtopic-separator>.</subtopic-separator>
- </server>
- </properties>
- <channels>
- <channel ref="my-polling-amf" />
- <channel ref="my-streaming-amf" />
- </channels>
- </destination>

- package
- {
- [RemoteClass(alias="cn.bestwiz.design.tc.Tick")]
- [Bindable]
- public class Tick
- {
- public var askPrice:Number;
- public var bidPrice:Number;
- public var midPrice:Number;
- public var tickTime:Date;;
- public var seqno:String;
- }
- }
- 再在main.mxml文件中,加入如下代码:
- <?xml version="1.0" encoding="utf-8"?>
- <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" viewSourceURL="srcview/index.html" height="378" width="426">
- <mx:Script>
- <![CDATA[
- import mx.controls.Alert;
- import mx.rpc.events.ResultEvent;
- import mx.messaging.Consumer;
- import mx.messaging.Channel;
- import mx.messaging.ChannelSet;
- import mx.messaging.events.MessageEvent;
- [Bindable]
- public var tick:Tick;
- public function submsg():void
- {
- Alert.show("click start");
- var consumer:Consumer = new Consumer();
- consumer.destination = "tick-data-feed";
- consumer.subtopic = "tick";
- consumer.channelSet = new ChannelSet(["my-streaming-amf"]);
- consumer.addEventListener(MessageEvent.MESSAGE, messageHandler);
- consumer.subscribe();
- Alert.show("click end");
- }
- private function messageHandler(event:MessageEvent):void
- {
- var tick:Tick = event.message.body as Tick;
- txtTick.text = tick.seqno;
- }
- ]]>
- </mx:Script>
- <mx:Panel x="32" y="43" width="362" height="302" layout="absolute" title="Watch Tick">
- <mx:Label x="72" y="43" text="Label" id="txtTick"/>
- <mx:Button x="132" y="41" label="Button" click="submsg(); "/>
- </mx:Panel>
- </mx:Application>
下面我们开始测试。
打开一个浏览器,在浏览器的地址栏中,输入:
http://localhost:8080/flex-blazeds/TickCacheServlet?cmd=start
再返回eclipse,在main.mxml文件上,单击右键,用Flex Application运行它。
之后,在打开的浏览器flash上,点击“Button”按纽,可以看到按纽之前的一个Label的Text一直有数字在增大。
原文:http://hi.baidu.com/tister/blog/item/fcfe4f66e9214e21ab184c5b.html