flex服务器端信息推送
服务器端信息推送就是是继alax之后新兴web技术。come也可称作反向ajax。成熟的java框架是DWR。 该功能可以实现:使服务器能实时地将更新的信息传送到客户端,而无须客户端发出请求,目前有两种实现方式,长轮询和iframe流。 长轮询长轮询是在打开一条连接以后保持,等待服务器推送来数据再关闭的方式。 iframe流iframe流方式是在页面中插入一个隐藏的iframe,利用其src属性在服务器和客户端之间创建一条长链接,服务器向iframe传输数据(通常是HTML,内有负责插入信息的javascript),来实时更新页面。(对于Iframe流没有接触过,暂时不做探究) 下面是一个基于轮询的实例: ? 1. 从adobe官网下载blazeds.war,这是一个压缩包,里面的包含META-INF和WEB-INF两个文件夹,目录结构如下:其中含META-INF仅包含MANIFEST.MF文件,WEB-INF中包含classes、flex、lib及src四个文件夹,其中flex文件夹中包含四个配置文件,lib中包含java和flex通讯所需要的jar包。 Flex文件夹中包含: Lib文件夹包含: 2. 创建Java后台的推送服务项目 新建一个DynamicWebProject,如:JavaPushServer 点击Next 点击Next 点击Finish,这时候创建了一个空的动态web项目,使用Tomcat6运行.这时候Eclipse中的见到的项目信息如下:Java Resources中的src为java源代码,Libraries中为java运行所依赖的jar包,如果已经配置好了Tomcat运行环境,则Apache Tomcat v6.0…目录下自动加载了Tomcat的jar包,和JRE System Library目录下的jar包 因为通讯需要blazeds,所以,这时候,可以将blazeds.war解压出来的两个文件夹替换掉刚才创建的web工程中WebContent文件目录下的内容.替换之后可以看到WebContent文件夹下内容变化情况: 以及JavaSources中的Libraries中Web App Libraries中增加了很多jar包,这些就是blazeds.war中所包含的jar包 引入blazeds.war之后,开始写Java代码:
创建名为Tick的java实体类: package com.eunut.vo; //实体类 public class Tick { privateString seqno; publicString getSeqno(){ returnseqno; } //字符类型,为测试用仅仅加了一个属性,可以为多个 publicvoid setSeqno(String seqno) { this.seqno=seqno; } } 然后再创建一个名为TickCacheServlet的Servlet 举例代码如下: import java.io.IOException; importjavax.servlet.ServletException; importjavax.servlet.http.HttpServlet; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; import com.eunut.vo.Tick; importflex.messaging.MessageBroker; importflex.messaging.messages.AsyncMessage; importflex.messaging.util.UUIDUtils; /** * Servlet implementation classTickCacheServlet */ public class TickCacheServletextends HttpServlet { privatestatic final long serialVersionUID = 1L; //线程 privatestatic FeedThread thread; /** * @see HttpServlet#HttpServlet() */ public TickCacheServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequestrequest,HttpServletResponse response) */ Protected void doGet(HttpServletRequest request,HttpServletResponse response) throwsServletException,IOException { //TODO Auto-generated method stub Stringcmd=request.getParameter("cmd"); if(cmd.equals("start")) { start(); } if(cmd.equals("stop")) { stop(); } } /** * @see HttpServlet#doPost(HttpServletRequestrequest,HttpServletResponse response) */ protectedvoid doPost(HttpServletRequest request,IOException { //TODO Auto-generated method stub super.doPost(request,response); } //初始化 publicvoid init() throws ServletException{ super.init(); } publicvoid destroy(){ super.destroy(); } //启动监听 Public void start(){ if(thread==null) { thread=newFeedThread(); 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(){ //总是无法获取msgBroker,web.xml需要有MessageBrokerServlet的配置信息 MessageBrokermsgBroker=MessageBroker.getMessageBroker(null); String clientID=UUIDUtils.createUUID(); Int i=0; while(running){ Tick tick=new Tick(); tick.setSeqno(String.valueOf(i)); System.out.println(i); AsyncMessage msg=new AsyncMessage(); msg.setDestination("tick-data-feed"); msg.setHeader(AsyncMessage.SUBTOPIC_HEADER_NAME,"tick"); msg.setClientId(clientID); msg.setMessageId(UUIDUtils.createUUID()); msg.setTimestamp(System.currentTimeMillis()); msg.setBody(tick); msgBroker.routeMessageToService(msg,null); i++; try { Thread.sleep(2000); } catch(InterruptedExceptione) { } } } } } 3. 修改Java后台的推送服务项目的配置文件:? ? ? ?
WebContentWEB-INFmessaging-config.xml <?xml version="1.0"encoding="UTF-8"?> <serviceid="message-service" class="flex.messaging.services.MessageService"> <adapters> <adapter-definitionid="actionscript"class="flex.messaging.services.messaging.adapters.ActionScriptAdapter"default="true" /> <!-- <adapter-definitionid="jms"class="flex.messaging.services.messaging.adapters.JMSAdapter"/>--> </adapters> <default-channels> <channelref="my-polling-amf"/> </default-channels> <!-- 增加配置信息 --> <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> </service> 以及services-config.xml中补充: <!-- 补充my-streaming-amf通道配置信息 --> <channel-definitionid="my-streaming-amf"class="mx.messaging.channels.StreamingAMFChannel"> <endpointurl="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-agentmatch-on="Firefox" kickstart-bytes="2048"max-streaming-connections-per-session="1"/> </user-agent-settings> </properties> </channel-definition> 同时,还要确保web.xml中包含下面的内容: <!-- MessageBroker Servlet-必须的,否则获取不到MessageBrokerServlet,无法发送消息 --> <servlet> <servlet-name>MessageBrokerServlet</servlet-name> <display-name>MessageBrokerServlet</display-name> <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class> <init-param> <param-name>services.configuration.file</param-name> <param-value>/WEB-INF/flex/services-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>MessageBrokerServlet</servlet-name> <url-pattern>/messagebroker/*</url-pattern> </servlet-mapping> <!-- 下面的是自动生成的 --> <servlet> <javaee:description></javaee:description> <javaee:display-name>TickCacheServlet</javaee:display-name> <servlet-name>TickCacheServlet</servlet-name> <servlet-class>TickCacheServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>TickCacheServlet</servlet-name> <url-pattern>/TickCacheServlet</url-pattern> </servlet-mapping>
4. 创建Flex客户端应用程序FlexPushClient.mxml: <?xml version="1.0"encoding="utf-8"?> <s:Applicationxmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"minWidth="955" minHeight="600"> <fx:Declarations> <!--将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <fx:Script> <![CDATA[ importcom.eunut.Tick; importmx.controls.Alert; importmx.messaging.ChannelSet; importmx.messaging.Consumer; importmx.messaging.channels.StreamingAMFChannel; importmx.messaging.events.ChannelEvent; importmx.messaging.events.MessageEvent; [Bindable] publicvar tick:Tick; publicfunction submsg():void { varconsumer:Consumer=new Consumer(); consumer.destination="tick-data-feed"; consumer.subtopic="tick"; consumer.addEventListener(MessageEvent.MESSAGE,messageHandler); varurl:String ="http://localhost:8080/JavaPushServer/"; varmyStreamingAMF:StreamingAMFChannel = newStreamingAMFChannel(url+"my-streaming-amf",url+"messagebroker/streamingamf"); varchannelSet:ChannelSet = new ChannelSet(); channelSet.addChannel(myStreamingAMF); consumer.channelSet= channelSet; // consumer.channelSet = newChannelSet(["my-streaming-amf"]); consumer.subscribe(); //开始接收 Alert.show("消费者初始化完毕!"); } privatefunction messageHandler(event:MessageEvent):void { vartick:Tick = event.message.body as Tick; txtTick.text= tick.seqno; } ]]> </fx:Script> <mx:Panelx="24" y="35" width="362" height="302"layout="absolute" title="Watch Tick"> <mx:Labelx="72" y="43" text="Label"id="txtTick"/> <mx:Buttonx="132" y="41" label="Button"click="submsg()"/> </mx:Panel> </s:Application> 还要创建Tick的as类: package com.eunut { importmx.rpc.remoting.RemoteObject; [RemoteClass(alias="com.eunut.vo.Tick")] //用于和java后台类转换alias为java类的命名空间,否则不能转换 [Bindable] publicclass Tick { publicfunction Tick() { } publicvar seqno:String; } } 配置此flex的应用程序的服务器为刚才创建好的JavaPushServer 好了,这样就可以了哦,现在就是如果看到推送的效果了,启动方式如下: 首先运行发布到Tomcat上的JavaPushServer,然后,打开客户端网址: http://localhost:8080/JavaPushServer/FlexPushClient.html 这时候显示的界面如下: 此时,点击Button按钮,启动监听程序. 然后,需要启动服务器端的监听: http://localhost:8080/JavaPushServer/TickCacheServlet?cmd=start 如果一切顺利,则可以看到Label显示的数字从0开始逐个增加. 通过调用: http://localhost:8080/JavaPushServer/TickCacheServlet?cmd=stop 就关闭服务器端的监听程序 注意:途中可能出现这样那样的问题,绝大部分都是因为配置文件不正确引起的,遇到问题时,一定要仔细查看配置文件中的内容是否正确. 路径问题:比如包名的层次结构是否相同,若不同则需要多处修改。 在这,在对servlet操作时,上述的路径也不是绝对的,参考自己web.xml中的配置进行相应修改 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |