由于这段时间做项目,需要到消息推送,所以专门做一个推送消息,包括设备邀请,锁的报警信息等,做这个消息推送,主要是前面tcp层响应要快,所以把一些数据库查询,或者消息推送,写到mq里面,这样子提高前面并发的链接,把这些消息推送拿出来,作为一个项目。
项目的构造如上图,没有web.xml文件,有点类似netty那些项目打包,所以在init包PushServerInit类中启动文件,
package com.pushserver.init;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class PushServerInit {
private static ApplicationContext context = null;
public PushServerInit() {
start();
}
public void start() {
try{
context = new ClassPathXmlApplicationContext("applicationContext-base.xml");
} catch (Exception err) {
err.printStackTrace();
return;
} finally {
}
}
public static void main(String[] args) {
new PushServerInit();
}
}
项目启动之后,这有个applicationContext-rabbitmq_consumers.xml,这个是mq消费者,专门监听写入这个队列的消息,
这个类网上很多,可以查找,这里需要修改2个地方,第一个就是exchange和routingKey,队列和钥匙,自己填写,其
次是<bean id="pushHandler" class="com.pushserver.rabbitmq.PushHandler"> 这个是我们自己处理消息这个类。
我在rabbitmq包中写了一个类PushHandler,这个是处理消息的类,这里主要是判断一些有用的消息才处理,比如
json格式错了,不处理,重要的是这里会加载消息处理类Map,然后找到对应的类类处理消息,主要是spring包中
SpringContextHolder加载这些类,因为这里每个消息处理类都有一个InfoType,根据InfoType来找到具体的类来处理,
这些类实现一个接口
package com.topband.pushserver.type.inter;
import java.util.Map;
public interface PushMessage {
public Integer getInfoType() throws Exception;//每个类的InfoType,消息必须带上来,否者不处理
public void pushMessage(Map map,int infoType)throws Exception;//类具体的业务处理
}
这些类也继承一个父类,BasePushMessage,主要是一些公用的方法或者变量。
当你业务处理完,需要返回数据;
第一:先把数据写到mq就可以了,按照一定格式
PushMessageBene pmb=new PushMessageBene();//消息返回处理类
String alert=getAlertResponse(userName,phone,email,deviceName,result);
pmb.setText(alert);
pmb.setInfoType(infoType);
pmb.setData(data); // 把它变json再用MqUtil.sendResponse处理就可以
MqUtil.sendResponse(jRedisClient, messageProducer, subSessionId, JsonUtil.toJSON(pmb));
String message=getIOSPushString(pmb.getSerial(), infoType, type, deviceId);// 这个是互相确认ios的消息格式
sendAPNS(main_userId, message, alert, "", infoType, type);//具体的推出去的有个方法如下
threadPool.server(token, message, alert, sound, jRedisClient, userId,infoType, type);//专门有线程推出去,方法类如下
package com.pushserver.push.ios;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.topband.cloud.common.redis.JRedisClient;
import com.topband.cloud.entity.Token;
import redis.clients.jedis.JedisCluster;
public class ThreadPool {
private ExecutorService exe = null;
private static final int POOL_SIZE = 100;
private IOSPushServerDbay iosPushServerDbayDefault;
public ThreadPool() {
exe = Executors.newFixedThreadPool(POOL_SIZE);
System.out.println("the server is ready...");
}
public void server(Token token, String message, String alert, String sound,
JRedisClient jRedisClient, String userId, int infoType,int type) {
String tokenStr = token.getPhoneToken();
String source = token.getSource();
IOSPushServerDbay iosPushServerDbay;
iosPushServerDbay = iosPushServerDbayDefault;
exe.execute(new WorkerIosPush(iosPushServerDbay, tokenStr, message, alert, sound, jRedisClient, userId,infoType,type));
}
class WorkerIosPush implements Runnable {//
private String token;
private String message;
private String alert;
private String sound;
private JRedisClient jRedisClient;
private String userId;
private IOSPushServerDbay iosPushServerDbay;
private int infoType;
private int type;
WorkerIosPush(IOSPushServerDbay iosPushServerDbay, String token, String message,
String alert, String sound, JRedisClient jRedisClient, String userId, int infoType,int type) {
this.token = token;
this.message = message;
this.alert = alert;
this.sound = sound;
this.jRedisClient = jRedisClient;
this.iosPushServerDbay = iosPushServerDbay;
this.userId = userId;
this.infoType=infoType;
this.type= type;
}
@Override
public void run() {
iosPushServerDbay.pushMessage(token, message, alert, sound, jRedisClient, userId, infoType,type);
}
}
public IOSPushServerDbay getIosPushServerDbayDefault() {
return iosPushServerDbayDefault;
}
public void setIosPushServerDbayDefault(
IOSPushServerDbay iosPushServerDbayDefault) {
this.iosPushServerDbayDefault = iosPushServerDbayDefault;
}
}
这些ios推送还要一些证书的,自己加载。
大概就是这样子。有错的,请指出,本人菜鸟,慢慢成长中。。。。。