利用Message的服务建立的Flex应用可以在多个客户端之间传送消息,下面以一个聊天室为例说明如何Message服务的Flex应用。
(1)打开14.2节当中创建的LCDSFlexStu项目,新建一个名称为LCDSMessage.mxml的应用。从http://activemq.apache.org下载activemq-4.0-M4.jar。将activemq-4.0-M4.jar拷贝到LCDSFlexStu项目下的WebCotent/WEB-INF/lib目录下。
(2)在WebCotent/WEB-INF/class目录下新建名称为“jndi.properties”文件。修改文件内容如下所示。这个文件是对jndi进行简单的配置。
java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory
java.naming.provider.url = tcp://localhost:61616
connectionFactoryNames = connectionFactory, queueConnectionFactory, topicConnectionFactory
topic.FlexChatTopic = chat.Topic
(3)在LCDSFlexStu项目当中新建名称“com.lcdsstu.message. ActiveMQBrokerStartListener”的Java文件。修改代码如下所示。
package com.lcdsstu.message;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.activemq.broker.BrokerService;
public class ActiveMQBrokerStartListener implements ServletContextListener {
BrokerService broker = new BrokerService();
//定义初始化上下文函数
public void contextInitialized(ServletContextEvent arg0) {
try{
broker.addConnector("tcp://localhost:61616?trace=true");
broker.start();
}catch(Exception e){
System.err.println(e.getMessage());
e.printStackTrace();
throw new RuntimeException(e);
}
}
//销毁上下文函数
public void contextDestroyed(ServletContextEvent arg0) {
try{
broker.stop();
}catch(Exception e){
System.err.println(e.getMessage());
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
(4)打开“WebCotent/WEB-INF”目录下web.xml文件在<web-app>标签中添加listener。添加代码如下所示。
<listener>
<listener-class>com.lcdsstu.message.ActiveMQBrokerStartListener</listener-class>
</listener>
通过添加这个listener是的com.lcdsstu.message.ActiveMQBrokerStartListener可以在服务器启动时就被启动。
(5)打开“WebCotent/WEB-INF/flex”目录下的messaging-config.xml文件修改内容如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<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-jms">
<properties>
<server>
<durable>false</durable>
<durable-store-manager>flex.messaging.durability.FileStoreManager</durable-store-manager>
</server>
<jms>
<destination-type>Topic</destination-type>
<message-type>javax.jms.ObjectMessage</message-type>
<connection-factory>topicConnectionFactory</connection-factory>
<destination-jndi-name>FlexChatTopic</destination-jndi-name>
<delivery-mode>NON_PERSISTENT</delivery-mode>
<message-priority>DEFAULT_PRIORITY</message-priority>
<acknowledge-mode>AUTO_ACKNOWLEDGE</acknowledge-mode>
<transacted-sessions>false</transacted-sessions>
<initial-context-environment>
<property>
<name>java.naming.factory.initial</name>
<value>org.apache.activemq.jndi.ActiveMQInitialContextFactory</value>
</property>
<property>
<name>java.naming.provider.url</name>
<value>tcp://localhost:61616</value>
</property>
</initial-context-environment>
</jms>
</properties>
<channels>
<channel ref="my-rtmp"/>
</channels>
<adapter ref="jms"/>
</destination>
</service>
(5)打开LCDSMessage.mxml文件修改代码如下所示。
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="initComp()">
<mx:Style>
global{
fontSize:12pt;
}
</mx:Style>
<!—引入消息发送和接收的标签-->
<mx:Producer id="producer" destination="chat-topic-jms"/>
<mx:Consumer id="consumer" destination="chat-topic-jms" message="messageHandler(event)"/>
<mx:Script>
<![CDATA[
//引入类库
import mx.messaging.messages.*;
import mx.messaging.events.*;
//绑定用户名和用户颜色
[Bindable]
private var userId:String;
[Bindable]
private var colorCode:Number;
//初始化时开始订阅消息,切换状态到登录
private function initComp():void
{
consumer.subscribe();
currentState = "logon";
}
//定义登录函数
public function logon():void
{
userId = tUserId.text;
//切换状态
currentState = "chat";
}
//发送消息函数
public function send():void
{
var message:AsyncMessage = new AsyncMessage();
//消息体的内容
message.body = {
userId: userId,
msg: msg.text,
color: colorCode
};
//发送消息
producer.send(message);
msg.text="";
}
//针对收到的消息进行处理
public function messageHandler(event:MessageEvent):void
{
//声明body对象
var body:Object = event.message.body;
if (log != null && body.userId != undefined)
{
var txt:String = body.userId + ": " + body.msg + "/n";
if (body.color == undefined)
{
log.text += txt;
}
else
{
var colorStr:String = "#" + Number(body.color).toString(16);
log.htmlText += "<font color=/"" + colorStr + "/">" + txt + "</font>";
}
log.validateNow();
log.verticalScrollPosition=log.maxVerticalScrollPosition;
}
}
]]>
</mx:Script>
<!—定义登录状态-->
<mx:states>
<mx:State name="logon">
<mx:AddChild>
<mx:VBox horizontalCenter="0" verticalCenter="0">
<mx:HBox width="100%">
<mx:Label text="昵称"/>
<mx:TextInput id="tUserId" enter="logon()" color="{colorCode}"/>
<mx:Button label="Logon" click="logon()"/>
</mx:HBox>
<mx:HBox>
<mx:Label text="颜色" />
<mx:ColorPicker id="colorPicker" change="colorCode = colorPicker.selectedColor"/>
</mx:HBox>
</mx:VBox>
</mx:AddChild>
</mx:State>
<!—定义聊天状态-->
<mx:State name="chat">
<mx:AddChild>
<mx:TextArea id="log" width="50%" height="50%" editable="false" horizontalCenter="0" verticalCenter="-25"/>
</mx:AddChild>
<mx:AddChild >
<mx:HBox width="50%" horizontalCenter="0" verticalCenter="89">
<mx:TextInput id="msg" enter="send()" width="100%"/>
<mx:Button label="Send" click="send()"/>
</mx:HBox>
</mx:AddChild>
</mx:State>
</mx:states>
</mx:Application>
上面的代码中定义了两个State分别为“logon”和“chat”。通过登录后进入聊天界面。然后通过Producer发送消息,通过Consumer接收消息。
注意:接收消息是个异步操作,所以需要定义处理接受信息的函数。
(6)保存并运行LCDSMessage.mxml应用。效果如图所示,在【昵称】的文本框中输入用户昵称。单击【颜色】颜色选择框。单击【登录】按钮,进入聊天界面如图所示
输入文本内容单击【发送】按钮可以看到刚刚发送聊天的内容。如图所示。开启浏览器输入LCDSMessage.mxml的地址。登录到聊天界面,输入聊天内容。如图所示。
所示。
这是原客户但界面内容显示了新客户端发送的消息如图
这样就完成了一个Message服务的聊天室项目。与传统的B/S聊天室不同。这个聊天室是无刷新页面的聊天室。