一 实习目的
利用消息中间件接口JMS、消息服务器ActiveMQ 和Java Swing实现一个简单的聊天工具,掌握消息中间件的应用。
二 实习要求
1、开发环境
Windows 7/XP,Eclipse, JDK1.6, apache-activemq-5.4.3, Java Swing
2、功能要求
(1)实现界面化的聊天工具,支持二人之间互发消息。
(2)界面上必须标注软件版权信息,包括姓名、学号等个性化信息。
(3)发送消息过程中,发送这首先把消息发送到消息服务器ActiveMQ,接收者从消息服务器上取消息;消息发送者和接收者不需要同时运行(在线),实现即使对方处在离线状态下也可以进行消息的发送和接收。
三 实习过程
1、ActiveMQ 安装和配置
(1)解压缩到apache-activemq-5.4.3-bin.zip到一个目录,例如C:\ apache-activemq-5.4.3
(2)配置文件在C:\apache-activemq-5.4.3\conf目录中:activemq.xml、credentials.properties、log4j.properties(本次实习不需要配置)。
(3)启动ActiveMQ:运行C:\ apache-activemq-5.4.3\bin\activemq.bat

(4)测试
ActiveMQ默认使用的TCP连接端口是61616, 通过查看该端口的信息可以测试ActiveMQ是否成功启动 netstat -an|find "61616"
在CMD下输入:netstat -an|find "61616" 显示下列信息表示成功。
TCP 0.0.0.0:61616 0.0.0.0:0 LISTENING

(5)登陆管理界面(本次实习不需要进入管理界面)
浏览器中输入:http://localhost:8161/admin/,用户名密码:admin,admin
2、开发
(1)在eclipse中导入并运行MessageMiddleWare中的三个例子,了解消息发送者、接收者编程。
(2)在建立一个工程,导入库文件activemq-all-5.4.3.jar(在apache-activemq-5.4.3\lib可找到该文件);也可直接在MessageMiddleWare工程中开发。
(3)使用Java Swing开发界面,界面上包括消息发送窗口、接收窗口(或二者在同一个窗口)、发送按钮等,界面下方需显示个性化的版权信息。
(4)参考MessageMiddleWare中的例子,编写消息发送类和接收类。发送类中需要连接ActiveMQ 服务器,创建队列,发送消息;接收类中需要ActiveMQ 服务器,读取发送者发送消息所用的队列。接收类必须实现为一个单独的线程,时刻侦听是否有消息到来。
(5)至少使用2个以上的队列,A给B发送消息时使用一个队列,B给A发送时使用另一个队列(若使用同一个队列,可能导致消息混乱)。
(6)开发完毕,打包为可运行包(不要把MessageMiddleWare放进去),双击可以直接运行。
3、相关软件见附件

ActiveMQ实现单线程多队列
发送者A:
package example3;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Sender {
private static final int SEND_NUMBER = 5;
ConnectionFactory connectionFactory;//连接工厂,JMS 用它创建连接
Connection connection = null;//JMS 客户端到JMS Provider 的连接
Session session;//一个发送或接收消息的线程
Destination destination;//消息的目的地
MessageProducer producer;//生产者,消息发送者
Sender() {
// TextMessage message;
// 构造ConnectionFactory实例对象,此处采用ActiveMq的实现jar
connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616");
try {
connection = connectionFactory.createConnection();//构造从工厂得到连接对象
connection.start();//启动
session = connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE);//获取操作连接,此处是Boolean.TRUE,是否支持事务,如果为true,则会忽略第二个参数
destination = session.createQueue("AQueue");//获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
producer = session.createProducer(destination);// 得到消息生成者【发送者】
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);// 设置不持久化,此处学习,实际根据项目决定
sendMessage(session, producer);// 构造消息,此处写死,项目就是参数,或者方法获取
session.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendMessage(Session session, MessageProducer producer) throws Exception {
for (int i = 1; i <= SEND_NUMBER; i++) {
TextMessage message = session.createTextMessage(this.getClass().getName()+" 发送的消息" + i);System.out.println(this.getClass().getName()+" 发送的消息" + i);// 发送消息到目的地方
producer.send(message);
}
}
public static void main(String[] args) {
new Sender();
}
}
发送者B
package example3;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Sender2 {
private static final int SEND_NUMBER = 5;
ConnectionFactory connectionFactory;//连接工厂,JMS 用它创建连接
Connection connection = null;//JMS 客户端到JMS Provider 的连接
Session session;//一个发送或接收消息的线程
Destination destination;//消息的目的地
MessageProducer producer;//生产者,消息发送者
Sender2() {
// TextMessage message;
// 构造ConnectionFactory实例对象,此处采用ActiveMq的实现jar
connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616");
try {
connection = connectionFactory.createConnection();//构造从工厂得到连接对象
connection.start();//启动
session = connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE);//获取操作连接,此处是Boolean.TRUE,是否支持事务,如果为true,则会忽略第二个参数
destination = session.createQueue("BQueue");//获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
producer = session.createProducer(destination);// 得到消息生成者【发送者】
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);// 设置不持久化,此处学习,实际根据项目决定
sendMessage(session, producer);// 构造消息,此处写死,项目就是参数,或者方法获取
session.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
public void sendMessage(Session session, MessageProducer producer) throws Exception {
for (int i = 1; i <= SEND_NUMBER; i++) {
TextMessage message = session.createTextMessage(this.getClass().getName()+" 发送的消息" + i);
System.out.println(this.getClass().getName()+" 发送的消息" + i);// 发送消息到目的地方
producer.send(message);
}
}
public static void main(String[] args) {
new Sender2();
}
}
接收者:
package example3;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Receiver{
ConnectionFactory connectionFactory;//连接工厂,JMS 用它创建连接
Connection connection = null;//JMS 客户端到JMS Provider 的连接
Session session;//一个发送或接收消息的线程
Destination destination;//A消息的目的地
MessageConsumer consumer;//A消费者,消息接收者
Destination destination2;//B消息的目的地
MessageConsumer consumer2;//B消费者,消息接收者
Receiver() {
try {
System.out.println("ActiveMQ 服务器正在接收信息");
connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616");
connection = connectionFactory.createConnection();//构造从工厂得到连接对象
connection.start();//启动
session = connection.createSession(Boolean.FALSE,Session.AUTO_ACKNOWLEDGE);//获取操作连接,此处是Boolean.FALSE,第二个参数为false时,paramB的值可为Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一个,此处为自动确认,客户端发送和接收消息不需要做额外的工作。哪怕是接收端发生异常,也会被当作正常发送成功。
destination = session.createQueue("AQueue");
consumer = session.createConsumer(destination);
destination2 = session.createQueue("BQueue");
consumer2 = session.createConsumer(destination2);
while (true) {
TextMessage message = (TextMessage) consumer.receiveNoWait();//设置接收者接收消息的时间,为了便于测试,这里设定为100s
TextMessage message2 = (TextMessage) consumer2.receiveNoWait();
if (null != message) {
System.out.println("收到A消息" + message.getText());
}
else if (null != message2) {
System.out.println("收到B消息" + message2.getText());
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
public static void main(String[] args) {
new Receiver();
}
}
执行结果如图所示:


1350



被折叠的 条评论
为什么被折叠?



