JMS activemq

语言是自己组织的。可能不专业,请读者见谅
有不对的地方,也欢迎大家指正

JMS有两种方式,一种是pub/sub,一种是(后续补充)
主要讨论pub/sub方式

pub/sub方式的工作流程:
首先订阅者(subscriber)向JMS容器订阅需要订阅的主题(topic),消息发布者发布消息,订阅了该主题的订阅者都能收到这个消息。(这是一对多的方式,类似于广播,个人理解),默认情况下,该消息不是持久的。即消息一发出,不管有没有人接受,都不会保存下来,即订阅者只能接收到自己订阅之后发布者发出的消息。
如果出现意外情况,订阅者突然断线了,发布者发布了一条消息,订阅者再连接上是不会收到消息的。解决这种情况的办法是订阅者中加个clientID。

JMS提供者(JMS Provider)也叫JMS服务器/容器

连接工厂Connection Factory:
是用来创建客户端到JMS容器之间JMS连接的工厂
context ctx = new InitialContext();
TopicConnectionFactory tcf = ctx.lookup("topic主题");

目的地:destinations
消息发布者发布消息的地方,即订阅者接收消息的来源地。因为目的地之注册在jms服务器的,所以我们只能通过JNDI查找。
Topic topic = (Topic)ctx.lookup("topic主题");

连接:connection
客户端与JMS提供者(容器)之间的连接
TopicConnection tc = tcf.createTopicConnection();

javax.jms.ExceptionListener

(请忽略:根据某些参数,生成clientID,向服务器注册JMS客户端)
需要导入activemq的jar包
第一种:最简单的activemq  默认端口:61616    发布者,订阅者示例
开启apache-activemq-5.11.1\bin下的activemq.bat
发布者:
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;

import org.apache.activemq.ActiveMQConnectionFactory;

public class TopicPublisher {

public static void main(String[] args) {
try {
//用户名,密码连接。连接方式:tcp。连接ip:port
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("admin","admin","tcp://127.0.0.1:61616");
Connection connection = connectionFactory.createConnection();
connection.start();

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//创建主题。连接时,发布者发布某个主题名,订阅者订阅想要订阅的主题名。
Topic topic = session.createTopic("TopicName");

//发布者  发布这个主题
MessageProducer producer = session.createProducer(topic);
//发送模式:非持久化         DeliveryMode.PERSISTENT:持久化
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

while(true){
TextMessage message = session.createTextMessage();
String text = "abcdefg";
message.setText(text);
producer.send(message);
System.out.println("Sent Message:" + message.getText());
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}

订阅者:
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;

import org.apache.activemq.ActiveMQConnectionFactory;

public class TopicSubscriber implements MessageListener {

private static ConnectionFactory connectionFactory = null;
private static Connection connection = null;
private static Session session = null;
private static Topic topic = null;
private static MessageConsumer consumer = null;

public TopicSubscriber(){
try {
connectionFactory = new ActiveMQConnectionFactory("admin","admin","tcp://127.0.0.1:61616");
connection = connectionFactory.createConnection();
// connection.setClientID("aaa");

session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//主题名:一定想要订阅的发布者的主题名
topic = session.createTopic("TopicName");
consumer = session.createConsumer(topic);
// consumer = session.createDurableSubscriber(topic, "aaa");

consumer.setMessageListener(this);
//开始监听
connection.start();
} catch (JMSException e) {
e.printStackTrace();
close();
}
}

private void close() {
try {
if(consumer != null){
consumer.close();
}
if(session != null){
session.close();
}
if(connection != null){
connection.close();
}

} catch (JMSException e) {
e.printStackTrace();
}
finally{
try {
if(consumer != null){
consumer.close();
}
if(session != null){
session.close();
}
if(connection != null){
connection.close();
}
consumer = null;
session = null;
connection = null;
} catch (JMSException e) {
e.printStackTrace();
}
}
}

@Override
public void onMessage(Message message) {
try {
TextMessage textMessage = (TextMessage) message;
System.out.println("Received message:" + textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
new TopicSubscriber();
}

}



第二种:SSL 安全通道加密的
发布者:

import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;

import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

import org.apache.activemq.ActiveMQSslConnectionFactory;

public class TopicSSLPublisher {

ActiveMQSslConnectionFactory factory;
Connection connection;
Session session;
String trustStore = "证书名";
String url = "ssl://IP:port";
Topic topic = null;
MessageProducer producer = null;

public TopicSSLPublisher(){
try {
factory = new ActiveMQSslConnectionFactory();
factory.setBrokerURL(url);
factory.setUserName("admin");
factory.setPassword("admin");
factory.setKeyAndTrustManagers(null, getTrustManagers(trustStore), new SecureRandom());
connection = factory.createConnection();

session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
topic = session.createTopic("topicName");
producer = session.createProducer(topic);

producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
connection.start();

while(true){
TextMessage message = session.createTextMessage();
String text = "sljdjk";
message.setText(text);
producer.send(message);
System.out.println("Sent Message:" + message.getText());

Thread.sleep(30000);
}
} catch (JMSException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

}

private TrustManager[] getTrustManagers(String trustStore){
try {
//KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(ClassLoader.getSystemResourceAsStream(trustStore),"证书密码".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
return tmf.getTrustManagers();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

public static void main(String[] args) {
new TopicSSLPublisher();
}
}

订阅者:

import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

import org.apache.activemq.ActiveMQSslConnectionFactory;

public class TopicSSLSubscriber implements MessageListener{
ActiveMQSslConnectionFactory factory;
Connection connection;
Session session;
private String trustStore = "证书名";
private String pwd = "pwd";
private String url = "ssl://ip:port";
Topic topic = null;
MessageConsumer consumer = null;

public TopicSSLSubscriber(){
try {
factory = new ActiveMQSslConnectionFactory();
factory.setBrokerURL(url);
factory.setUserName("admin");
factory.setPassword("admin");

factory.setKeyAndTrustManagers(null, getTrustManagers(trustStore), new SecureRandom());
connection = factory.createConnection();
// connection.setClientID("id");//保证唯一性就行
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
topic = session.createTopic("topicName");

consumer = session.createConsumer(topic);
// consumer = session.createDurableSubscriber(topic, "id");
//开始监听
connection.start();

} catch (JMSException e) {
e.printStackTrace();
close();
}


}

private TrustManager[] getTrustManagers(String trustStore){
try {
//KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(ClassLoader.getSystemResourceAsStream(trustStore),pwd.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
return tmf.getTrustManagers();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

public static void main(String[] args) {
new TopicSSLSubscriber();
}

@Override
public void onMessage(Message message) {
try {
TextMessage textMessage = (TextMessage) message;
System.out.println("Received message:" + textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}

private void close() {
try {
if(consumer != null){
consumer.close();
}
if(session != null){
session.close();
}
if(connection != null){
connection.close();
}

} catch (JMSException e) {
e.printStackTrace();
}
finally{
try {
if(consumer != null){
consumer.close();
}
if(session != null){
session.close();
}
if(connection != null){
connection.close();
}
consumer = null;
session = null;
connection = null;
} catch (JMSException e) {
e.printStackTrace();
}
}
}


private KeyManager[] getKetManagers(String trustStore){
try {
//KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(ClassLoader.getSystemResourceAsStream(trustStore),pwd.toCharArray());
KeyManagerFactory tmf = KeyManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore,pwd.toCharArray());
return tmf.getKeyManagers();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
}
return null;
}
}



在这个过程中订阅者中添加clientID的就是解决突发情况的。clientID要保证唯一性。



自己下个activemq的包,activemq的下载连接
自己打开activemq,运行网页,观察网页中发布者,订阅者之间接收消息的情况。
和加了clientID时的情况。
知识点:加了clientID的情况要分为,运行这个主题之前,和运行这个主题之后两种情况。

代码中牵扯到的证书,怎样查看证书的相关知识,将在以后简单介绍

猜你喜欢

转载自1282084618.iteye.com/blog/2234801