本文以ActiveMQ 消息服務器中間件爲例。
實現的步驟如下:
1)實例化連接 工廠ConnectionFactory,主要設置的參數爲連接到消息服務器中間件的用戶名,密碼及url.
2)通過連接工廠ConnectionFactory獲取到消息中間件的連接Connection.
3)啓動連接,並創建消息會話Session,用於發送或接收消息的線程
4)通過消息會話創建消息目的地Destination
5)創建消息生產者MessageProducer或消息消費者MessageConsumer
6)通過消息生產者MessageProducer發送消息或通過消息消費者MessageConsumer接收消息
7)關閉並釋放連接資料
具體的實現代碼如下:
發送消息客戶端代碼如下:
import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import com.afmobi.jms.model.User;
public class QueueSender {
private ConnectionFactory connFactory;
private Connection conn;
private Session session;
private MessageProducer producer;
private boolean stop=false;
public void execute() throws Exception {
// 連接工廠
// 設置用戶名和密碼,這個用戶名和密碼在conf目錄下的credentials.properties文件中
connFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
// 連接到JMS提供者
conn = connFactory.createConnection();
conn.start();
// 事務性會話,自動確認消息
// 第一個參數是否使用事務:當消息發送者向消息提供者(即消息代理)發送消息時,消息發送者等待消息代理的確認,沒有迴應則拋出異常,消息發送程序負責處理這個錯誤。
// 第二個參數消息的確認模式:
// AUTO_ACKNOWLEDGE :
// 指定消息提供者在每次收到消息時自動發送確認。消息只向目標發送一次,但傳輸過程中可能因爲錯誤而丟失消息。
// CLIENT_ACKNOWLEDGE :
// 由消息接收者確認收到消息,通過調用消息的acknowledge()方法(會通知消息提供者收到了消息)
// DUPS_OK_ACKNOWLEDGE : 指定消息提供者在消息接收者沒有確認發送時重新發送消息(這種確認模式不在乎接收者收到重複的消息)
session = conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
// 創建目標,就創建主題也可以創建隊列
Destination destination = session.createQueue("queue.hello");
// 消息生產者
producer = session.createProducer(destination);
// 設置持久化,DeliveryMode.PERSISTENT和DeliveryMode.NON_PERSISTENT
// 如果DeliveryMode沒有設置或者設置爲NON_PERSISTENT,那麼重啓MQ之後消息就會丟失。
producer.setDeliveryMode(DeliveryMode.PERSISTENT);// 持久化
// 發送消息
while(!stop){
Thread.sleep(1000);
sendObject(session, producer);
session.commit();// 在事務會話中,只有commit之後,消息纔會真正到達目的地
System.out.println("已發送消息");
}
producer.close();
session.close();
conn.close();
}
// 對象消息
public void sendObject(Session session, MessageProducer producer)
throws JMSException {
User user = new User();
user.setAccount("petty");
user.setName("happy");
ObjectMessage objectMessage = session.createObjectMessage();
objectMessage.setObject(user);
producer.send(objectMessage);
}
// 字節消息
public void sendBytes(Session session, MessageProducer producer)
throws JMSException {
String s = "BytesMessage字節消息";
BytesMessage bytesMessage = session.createBytesMessage();
bytesMessage.writeBytes(s.getBytes());
producer.send(bytesMessage);
}
// 流消息
public void sendStream(Session session, MessageProducer producer)
throws JMSException {
StreamMessage streamMessage = session.createStreamMessage();
streamMessage.writeString("streamMessage流消息");
streamMessage.writeLong(55);
producer.send(streamMessage);
}
// 鍵值對消息
public void sendMap(Session session, MessageProducer producer)
throws JMSException {
MapMessage mapMessage = session.createMapMessage();
mapMessage.setLong("age", 25);
mapMessage.setDouble("sarray", new Double(6555.5));
mapMessage.setString("username", "鍵值對消息");
producer.send(mapMessage);
}
// 文本消息
public void sendText(Session session, MessageProducer producer)
throws JMSException {
TextMessage textMessage = session.createTextMessage("文本消息");
producer.send(textMessage);
}
}
import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import com.afmobi.jms.model.User;
public class QueueReceiver implements MessageListener{
private ConnectionFactory connFactory;
private Connection conn;
private Session session;
private boolean stop=false;
public void execute()throws Exception{
//連接工廠
// 設置用戶名和密碼,這個用戶名和密碼在conf目錄下的credentials.properties文件中
connFactory=new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616");
//連接到JMS提供者
conn=connFactory.createConnection();
conn.start();
//事務性會話,自動確認消息
// 第一個參數是否使用事務:當消息發送者向消息提供者(即消息代理)發送消息時,消息發送者等待消息代理的確認,沒有迴應則拋出異常,消息發送程序負責處理這個錯誤。
// 第二個參數消息的確認模式:
// AUTO_ACKNOWLEDGE : 指定消息提供者在每次收到消息時自動發送確認。消息只向目標發送一次,但傳輸過程中可能因爲錯誤而丟失消息。
// CLIENT_ACKNOWLEDGE : 由消息接收者確認收到消息,通過調用消息的acknowledge()方法(會通知消息提供者收到了消息)
// DUPS_OK_ACKNOWLEDGE : 指定消息提供者在消息接收者沒有確認發送時重新發送消息(這種確認模式不在乎接收者收到重複的消息)
session=conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
// 創建目標,就創建主題也可以創建隊列
Destination destination=session.createQueue("queue.hello");
//消息的消費者
MessageConsumer consumer=session.createConsumer(destination);
consumer.setMessageListener(this);
//等待接收消息
while(!stop){
Thread.sleep(5000);
}
consumer.close();
session.close();
conn.close();
}
public void onMessage(Message m) {
try{
if(m instanceof TextMessage){//接收文件消息
TextMessage message=(TextMessage)m;
System.out.println(message.getText());
}else if(m instanceof MapMessage){//接收鍵值消息
MapMessage message=(MapMessage)m;
System.out.println(message.getLong("age"));
System.out.println(message.getDouble("sarray"));
System.out.println(message.getString("username"));
}else if(m instanceof StreamMessage){//接收流消息
StreamMessage message=(StreamMessage)m;
System.out.println(message.readString());
System.out.println(message.readLong());
}else if(m instanceof BytesMessage){
byte[] b=new byte[1024];
int len=-1;
BytesMessage message=(BytesMessage)m;
while((len=message.readBytes(b))!=-1){
System.out.println(new String(b,0,len));
}
}else if(m instanceof ObjectMessage){
ObjectMessage message=(ObjectMessage)m;
User user=(User)message.getObject();
System.out.println("name:"+user.getAccount()+";info:"+user.getName());
}else{
System.out.println(m);
}
session.commit();
}catch(JMSException e){
e.printStackTrace();
}
}
}
以上代碼是PTP即點對點消息模式的示例,如果採用Sub/Pub即發佈/訂閱者消息模式,基本代碼的實現過程都一樣,只需把
創建消息目的地的代碼
Destination destination = session.createQueue("queue.hello");
修改爲
Destination destination=session.createTopic("topic.hello");
即可。