最近需要用到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要注册多个主动推通道,那么就抛出异常。