文介绍怎样使用Flex数据推送实现前台消息订阅,是在前面Flex+BlazeDS+Spring整合基础上进行的,利用Spring来简化配置。环境准备:
1.完成Flex+BlazeDS+Spring整合
2.修改项目根目录下.flexProperties文件中serverContextRoot为项目名,否则后台接收不到前台订阅信息(此处浪费了我很多时间,一定注意)
修改配置文件
1.修改WEB-INF/flex/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>
2.修改Spring配置文件applicationContext.xml,把<flex:message-broker/>替换为如下代码:
<!-- allow-subtopics设为true,允许订阅者订阅指定主题消息 --> <flex:message-destination id="data_push" allow-subtopics="true" subtopic-separator="."/> <flex:message-broker> <flex:message-service default-channels="my-streaming-amf,my-polling-amf"/> </flex:message-broker> <bean id="messageTemplate" class="org.springframework.flex.messaging.MessageTemplate" />
其中"my-streaming-amf,my-polling-amf"要在services-config.xml中配置,messageTemplate在代码中实现推送功能。
后台推送数据
1.添加推送数据Service,代码如下,注意msg设置的各参数,前后台及配置文件都要对应
package demo.flex.service; import javax.annotation.Resource; import org.springframework.flex.messaging.AsyncMessageCreator; import org.springframework.flex.messaging.MessageTemplate; import org.springframework.stereotype.Service; import flex.messaging.messages.AsyncMessage; import flex.messaging.util.UUIDUtils; @Service public class DataPushService { @Resource private MessageTemplate messageTemplate; public void push(String topic, Object data) { messageTemplate.send(new CustomAsyncMessageCreator(topic, data)); } class CustomAsyncMessageCreator implements AsyncMessageCreator { private String topic; private Object data; public CustomAsyncMessageCreator(String topic, Object data) { this.topic = topic; this.data = data; } @Override public AsyncMessage createMessage() { AsyncMessage msg = new AsyncMessage(); msg.setClientId(UUIDUtils.createUUID()); msg.setMessageId(UUIDUtils.createUUID()); msg.setTimestamp(System.currentTimeMillis()); msg.setDestination("data_push"); // 必须和配置文件中message-destination相同 msg.setHeader("DSSubtopic", topic); // 设置订阅主题 msg.setBody(data); return msg; } } }
2.添加控制数据开始推送及结束推送Controller,每隔一秒推送当前系统时间
package demo.flex.mvc; import java.text.SimpleDateFormat; import java.util.Date; import javax.annotation.Resource; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import demo.flex.service.DataPushService; @Controller public class DataPush { private static FeedThread thread; @Resource private DataPushService dataPushService; @RequestMapping("push") public String push(String cmd) throws Exception { if ("start".equals(cmd)) { start(); } else { stop(); } return "push"; } private void start() { if (thread == null) { thread = new FeedThread(); thread.start(); } System.out.println("开始数据推送..."); } private void stop() { thread.running = false; thread = null; System.out.println("结束数据推送..."); } public class FeedThread extends Thread { public boolean running = true; private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public void run() { while (running) { String time = sdf.format(new Date()); System.out.println(">>>>>>>>>>>" + time); // time为订阅主题 dataPushService.push("time", time); try { Thread.sleep(1000); } catch (InterruptedException e) { } } } } }
3.为使DataPush能够正常运行,修改web.xml及applicationContext.xml配置,添加如下代码:
<!-- mvc mapping--> <servlet-mapping> <servlet-name>Spring MVC Dispatcher Servlet</servlet-name> <url-pattern>/mvc/*</url-pattern> </servlet-mapping>
<mvc:annotation-driven /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> </bean>
前台订阅功能
前台FlexDemo.mxml中添加如下代码,订阅主题为time的消息,用于显示后台系统时间
<s:Group horizontalCenter="0"> <s:Label text="系统时间:"/> <s:TextInput id="timeText" text="systime" editable="false" x="80" y="0" width="200"/> <s:Button label="显示时间" x="60" y="40" click="showTimeHandler(event)"/> <s:Button label="隐藏时间" x="155" y="40" click="hideTimeHandler(event)"/> </s:Group>
private var consumer:Consumer; protected function showTimeHandler(event:MouseEvent):void { if (consumer == null) { consumer = new Consumer(); // consumer设置的参数要与后台配置对应 consumer.destination = "data_push"; consumer.channelSet = new ChannelSet(["my-streaming-amf","my-polling-amf"]); // 只能收到主题为time的订阅消息 consumer.subtopic = "time"; //添加message的监听,当后台有消息发送时,调用messageHandler consumer.addEventListener(MessageEvent.MESSAGE, messageHandler); // 订阅 consumer.subscribe(); } } protected function hideTimeHandler(event:MouseEvent):void { if (consumer != null) { // 取消订阅 consumer.unsubscribe(); consumer.removeEventListener(MessageEvent.MESSAGE, messageHandler); consumer = null; timeText.text = "systime"; } } private function messageHandler(event:MessageEvent):void { var time:String = event.message.body as String; timeText.text = time; }
消息订阅也可以采用MultiTopicProducer,能够在单个消息处理程序中同时订阅主题,通过addSubscription(topic)方法订阅主题,removeSubscription(topic)取消订阅。Consumer只能订阅单个主题。
所有代码已写完,启动项目进行测试!
1.订阅消息:打开链接http://localhost:8080/FlexDemo/FlexDemo.html,点击显示时间订阅time消息,点击隐藏时间取消订阅
2.推送消息:打开链接http://localhost:8080/FlexDemo/mvc/push?cmd=start推送消息,http://localhost:8080/FlexDemo/mvc/push?cmd=stop停止推送
经过测试,my-streaming-amf、my-polling-amf两个通道都可以实现消息推送订阅,但my-streaming-amf发送订阅请求后会一直维护这一个请求直到取消订阅,my-polling-amf会根据配置文件中设定的时间间隔,每过一段时间发送一次订阅请求,获得后台订阅的信息。
最后附完整代码下载地址:http://download.csdn.net/detail/sjepy/5522399