Message filtering
Messaging Service允许给Producer组件添加message headers 或者增加subtopic 信息。然后Consumer组件在调用subscribe()方法的时候会把它的过滤信息发送回服务器进行消息过滤 。
对于更高级复杂的消息 ,建议使用mx.messaging.MultiTopicConsumer 和mx.messaging.MultiTopicProducer 。
Using selectors:使用message headers
Producer :message header的名字不能为 “JMS ”和“DS ”这些保留字符串 。
var message:AsyncMessage = new AsyncMessage(); message.headers = new Array(); message.headers["prop1"] = 5; message.body = input.text; producer.send(message);
Consumer :使用Consumer.selector 来制定一个message selector
<mx:Consumer id="consumer" destination="chat" selector="prop1 > 4" message="messageHandler(event);"/>
Using subtopics
<destination id="chat"> <properties> <network> <subscription-timeout-minutes>0</subscription-timeout-minutes> </network> <server> <message-time-to-live>0</message-time-to-live> <allow-subtopics>true</allow-subtopics> <subtopic-separator>.</subtopic-separator> </server> </properties> <channels> <channel ref="my-polling-amf"/> </channels> </destination>
Configuring the Messaging Service
示例
<service id="message-service" class="flex.messaging.services.MessageService"> <adapters> <adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true"/> <adapter-definition id="jms" class="flex.messaging.services.messaging.adapters.JMSAdapter"/> </adapters> <destination id="chat-topic"> <properties> <server> <message-time-to-live>0</message-time-to-live> </server> </properties> <channels> <channel ref="samples-rtmp"/> <channel ref="samples-amf-polling"/> </channels> </destination> </service>
Configuring the adapter
如果 在destination里不指定 adapter,那么destination会使用缺省的 在service里<adapters>标签中定义的adapter。
给destination自定义引用adapter
<destination id="chat-topic"> <adapter ref="actionscript"/> </destination>
Defining the destination
<destination id="chat-topic"> <properties> <network> <throttle-inbound policy="ERROR" max-frequency="50"/> <throttle-outbound policy="ERROR" max-frequency="500"/> </network> </properties> </destination>
subscription-timeout-minutes : 订阅者自动退订时间 ;即N分钟内没有收到message就自动退订;该值默认为0,表示永远不会强制退订。
throttle-inbound :max-frequency属性表示该destination每秒接收 消息的最高值;policy属性表示当达到mesage limit的时候该如何处理:NONE :不采取任何措施;ERROR :不接收多出的mesage并且发送error到客户端;IGNORE :不接收多出的message但不发送error到客户端。
throttle-outbound :max-frequency属性表示该destination每秒发送 消息的最高值;policy属性表示当达到mesage limit的时候该如何处理:NONE :不采取任何措施;ERROR :不发送多出的mesage并且发送error到客户端;IGNORE :不发送多出的 message但不发送error到客户端。
<destination id="chat-topic"> <properties> ... <server> <message-time-to-live>0</message-time-to-live> </server> </properties> </destination>
allow-subtopics :允许 destination中使用subtopics 。
cluster-message-routing :destination使用的message-route的模式:server-to-server (default) 和 broadcast 。前者表示只有data message路由到servers,但是subscribe and unsubscribe messages全部通过cluster(集群)来broadcast ;后者表示全部messages全部通过cluster来broadcast。
message-time-to-live :表示某条message的存活时间(毫秒) ,超过这个时间就会被抛弃;0表示这条message永远不会过期。
send-security-constraint :接收消息安全限制,针对Producer 组件,下面有示例代码
subscribe-security-constraint :发送消息安全限制,针对Consumer 组件,下面有示例代码
subtopic-separator :设置subtopic的通配符 ;默认是“.”。
<destination id="chat-topic"> ... <channels> <channel ref="samples-rtmp"/> <channel ref="samples-amf-polling"/> </channels> ... </destination>
<destination id="chat"> ... <properties> <server> <send-security-constraint ref="sample-users"/> <subscribe-security-constraint ref="sample-users"/> </server> </properties> ... </destination>
Creating a custom Message Service adapter
package com; import java.util.Random; import flex.messaging.MessageBroker; import flex.messaging.io.ArrayCollection; import flex.messaging.messages.AsyncMessage; import flex.messaging.messages.Message; import flex.messaging.services.MessageService; import flex.messaging.services.ServiceAdapter; import flex.messaging.util.UUIDUtils; public class RandomNumberGenerator extends ServiceAdapter { private static DataGenerator thread; private static ArrayCollection randomNumbers = new ArrayCollection(); public RandomNumberGenerator() { Random random = new Random(); for (int i = 0; i < 6; i++) { randomNumbers.add(new Integer(random.nextInt(100))); } } public void start() { if (thread == null) { thread = new DataGenerator(); thread.start(); } } public void stop() { thread.running = false; thread = null; } public static class DataGenerator extends Thread { public boolean running = true; public void run() { MessageBroker msgBroker = MessageBroker.getMessageBroker(null); String clientID = UUIDUtils.createUUID(); Random random = new Random(); while (running) { randomNumbers.clear(); { for (int i = 0; i < 6; i++) { randomNumbers.add(new Integer(random.nextInt(100))); } } AsyncMessage msg = new AsyncMessage(); msg.setDestination("RandomDataPush"); msg.setClientId(clientID); msg.setMessageId(UUIDUtils.createUUID()); msg.setBody(randomNumbers); msgBroker.routeMessageToService(msg, null); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public Object invoke(Message message) { if (message.getBody().equals("New")) { return randomNumbers; } else { AsyncMessage newMessage = (AsyncMessage) message; newMessage.setBody(randomNumbers); MessageService msgService = (MessageService) getDestination().getService(); msgService.pushMessageToClients(newMessage, false); } return null; } }
<adapters> ... adapter-definition id="cfgateway" class="foo.bar.SampleMessageAdapter"/> ... </adapters> <destination id="chat"> <adapter ref="cfgateway" /> <channels> <channel ref="my-polling-amf"/> </channels> </destination>