package com.liuxinglanyue.session.rocketmq;
import java.util.List;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Session;
import org.apache.catalina.session.StandardManager;
import org.apache.catalina.session.StandardSession;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import com.alibaba.rocketmq.client.exception.MQBrokerException;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.common.message.Message;
import com.alibaba.rocketmq.common.message.MessageExt;
import com.alibaba.rocketmq.remoting.exception.RemotingException;
import com.liuxinglanyue.session.redis.share.KryoSerializer;
public class RocketMqManager extends StandardManager {
private final Log log = LogFactory.getLog(RocketMqManager.class);
public final String jvmRoute = getJvmRoute();
public final String producerGroup = "TS_Producer:" + jvmRoute;
public final String consumerGroup = "TS_Consumer:" + jvmRoute;
public final String topic = "TS";
public final String add_session = "ADD_Session:";
public final String del_session = "DEL_Session:";
public final String add_attribute = "ADD_Attribute";
public final String del_attribute = "DEL_Attribute";
public final String expire_session = "EXP_Session";
public final String tag_add_session = add_session + jvmRoute;
public final String tag_del_session = del_session + jvmRoute;
public final String tag_add_attribute = add_attribute + jvmRoute;
public final String tag_del_attribute = del_attribute + jvmRoute;
public final String tag_exp_session = expire_session + jvmRoute;
protected DefaultMQProducer producer;
protected DefaultMQPushConsumer consumer;
protected String namesrvAddr = "112.124.114.224:9876";
protected boolean debug = false;
@Override
protected StandardSession getNewSession() {
return new RocketMqSession(this);
}
@Override
protected void startInternal() throws LifecycleException {
super.startInternal();
startProducer();
startConsumer();
}
private void startProducer() {
producer = new DefaultMQProducer(producerGroup);
producer.setNamesrvAddr(namesrvAddr);
producer.setInstanceName("Producer");
try {
producer.start();
} catch (MQClientException e) {
throw new RuntimeException("RocketMQ Producer start error", e);
}
}
private void startConsumer() {
consumer = new DefaultMQPushConsumer(consumerGroup);
consumer.setNamesrvAddr(namesrvAddr);
consumer.setInstanceName("Consumer");
try {
consumer.subscribe(topic, "*");
//register listener
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
if(debug) {
log.info(Thread.currentThread().getName() + " Receive New Messages: " + msgs.size());
}
for(MessageExt msg : msgs) {
if(topic.equalsIgnoreCase(msg.getTopic())) {
String tag = msg.getTags();
if(tag.endsWith(jvmRoute)) {
continue;
}
Session session = (Session) KryoSerializer.read(msg.getBody());
if(tag.startsWith(add_session)) {
addWithOutSend(session);
} else if(tag.startsWith(del_session)) {
removeWithOutSend(session, false);
} else if(tag.startsWith(add_attribute)) {
addWithOutSend(session);
} else if(tag.startsWith(del_attribute)) {
addWithOutSend(session);
} else if(tag.startsWith(expire_session)) {
addWithOutSend(session);
}
} else {
log.error(Thread.currentThread().getName() + " Receive Error Messages, Topic:" + msg.getTopic());
}
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
} catch (MQClientException e) {
throw new RuntimeException("RocketMQ Consumer start error", e);
}
}
@Override
public void add(Session session) {
super.add(session);
send(session, tag_add_session);
}
@Override
public void remove(Session session, boolean update) {
super.remove(session, update);
send(session, tag_del_session);
}
@Override
public void changeSessionId(Session session) {
super.changeSessionId(session);
send(session, tag_add_session);
}
public SendResult send(Session session, String tag) {
byte[] body = KryoSerializer.write(session);
Message msg = new Message(topic, tag, session.getIdInternal(), body);
try {
return producer.send(msg);
} catch (MQClientException | RemotingException | MQBrokerException | InterruptedException e) {
log.error("网络错误!", e);
}
return null;
}
public void removeWithOutSend(Session session, boolean update) {
super.remove(session, update);
}
public void addWithOutSend(Session session) {
super.add(session);
}
@Override
protected void stopInternal() throws LifecycleException {
super.stopInternal();
producer.shutdown();
consumer.shutdown();
}
public String getNamesrvAddr() {
return namesrvAddr;
}
public void setNamesrvAddr(String namesrvAddr) {
this.namesrvAddr = namesrvAddr;
}
public boolean isDebug() {
return debug;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
}