最近需要用到flex的服务器主动推技术,网上查了下资料,大部分都是相互抄袭,而且说得也并不是可以执行,当然不排除是因为我电脑环境的原因。现在摸索了下,把自己的代码及配置发出来,供大家参考。
既然是服务器主动推,那么肯定有服务器端、客户端以及连接服务器和客户端的通道,服务器端和客户端通过代码实现,而中间的连接通道就通过blazeds来实现,我将代码都整合进了一个工具类,
那么下面详细说明一下。
服务器端代码:
/** * 通过建立的通道主动推送到客户端,对于同一个通道,destination和subtopic不变 * * @param destination * 主动推的通道名称,一般不用修改 * @param subtopic * 主动推的客户端接收头信息标识,一般不用修改 * @param type * 发送消息的标识 * @param message * 要主动推送的消息对象 */ public static void autoPushToClient(String destination, String subtopic,String type, Object message) { MessageBroker msgBroker = MessageBroker.getMessageBroker(null); String clientID = UUIDUtils.createUUID(); AsyncMessage msg = new AsyncMessage(); msg.setDestination(destination); msg.setHeader("DSSubtopic", subtopic); msg.setClientId(clientID); msg.setMessageId(UUIDUtils.createUUID()); msg.setTimestamp(System.currentTimeMillis()); msg.setBody(new AsyncMessageBean(type, message));// 此处的Body是推送到客户端的实体类,由自己定义 msgBroker.routeMessageToService(msg, null);// 执行,推送任务 }客户端代码:
/** * 注册客户端监听服务端主动推的通道 * messageHandler方法用于接收消息,参数应为event:mx.messaging.events.MessageEvent */ public static function registerAsyncClient(destination:String,subtopic:String,url:String,channel:String,endpoint:String,messageHandler:Function):void { var consumer:Consumer = new Consumer(); consumer.destination = destination;// 这里的destination和subtopic应和服务器端得相同 consumer.subtopic = subtopic; // 此处的url要写全,如http://localhost:8080 // channel为blazeds所管理,举例为/example/my-streaming-amf // endpoint为blazeds所管理,举例为/examlple/messagebroker/streamingamf var myStreamingAMF:StreamingAMFChannel = new StreamingAMFChannel(url + channel, url + endpoint); var channelSet:ChannelSet = new ChannelSet(); channelSet.addChannel(myStreamingAMF); consumer.channelSet = channelSet; consumer.addEventListener(MessageEvent.MESSAGE, messageHandler);// messageHandler是获取到服务 器主动推的内容后调用的方法 consumer.subscribe(); }
通道由blazeds实现,对我们来说表现就为配置文件。其中my-polling-amf是blazeds默认生成,而且据我测试下来,必须在主动推的通道中包含my-polling-amf才行,具体原因尚不清楚。
首先是services-config.xml,这里的channel和endpoint即为客户端代码中所写的,里面配置了不同的浏览器的最大连接数
<channel-definition id="my-polling-amf" class="mx.messaging.channels.AMFChannel"> <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amfpolling" class="flex.messaging.endpoints.AMFEndpoint"/> <properties> <polling-enabled>true</polling-enabled> <polling-interval-seconds>4</polling-interval-seconds> </properties> </channel-definition> <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>50</max-streaming-clients> <server-to-client-heartbeat-millis>5000</server-to-client-heartbeat-millis> <user-agent-settings> <!-- MSIE 5, 6, 7 default max number of permanent HTTP connections is 2. --> <user-agent match-on="MSIE" kickstart-bytes="2048" max-streaming-connections-per-session="13"/> <!-- MSIE 8 max number is 6. --> <user-agent match-on="MSIE 8" kickstart-bytes="2048" max-streaming-connections-per-session="15"/> <!-- Firefox 1, 2 max number is 2. --> <user-agent match-on="Firefox" kickstart-bytes="2048" max-streaming-connections-per-session="13"/> <!-- Firefox 3 max number is 6. --> <user-agent match-on="Firefox/3" kickstart-bytes="2048" max-streaming-connections-per-session="15"/> <!-- Safari 3, 4 max number is 4. --> <!-- Chrome 0, 1, 2 max number is 6. --> <user-agent match-on="Chrome" kickstart-bytes="2048" max-streaming-connections-per-session="15"/> <!-- Opera 7, 9 max number is 4.--> <user-agent match-on="Opera" kickstart-bytes="2048" max-streaming-connections-per-session="13"/> <!-- Opera 8 max number is 8. --> <user-agent match-on="Opera 8" kickstart-bytes="2048" max-streaming-connections-per-session="17"/> <!-- Opera 10 max number is 8. --> <user-agent match-on="Opera 10" kickstart-bytes="2048" max-streaming-connections-per-session="17"/> </user-agent-settings> </properties> </channel-definition>然后就是messaging-config.xml,这里的destination即为客户端和服务端代码中所写的destination
<default-channels> <channel ref="my-polling-amf"/> </default-channels> <destination id="alarm-message-show"> <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>至此,主动推就完成配置了,剩下的就是调用工具类的方法来进行了。
在我测试的过程中,发现同一个flex client不能向服务器端注册多个不同的主动推的通道,跟踪blazeds代码结果时,blazeds将每个flex client的id和服务器端进行了绑定,一旦发现同一个client id要注册多个主动推通道,那么就抛出异常。
烦请发现能进行多个主动推通道注册的朋友告诉我一下应该怎么配置。
转载请注明出处,谢谢!