├── .gitignore ├── .gradle ├── 3.5 │ ├── file-changes │ │ └── last-build.bin │ └── taskHistory │ │ └── taskHistory.lock └── buildOutputCleanup │ ├── built.bin │ ├── cache.properties │ └── cache.properties.lock ├── README.md ├── build.gradle ├── settings.gradle └── src └── main ├── java └── com │ └── even │ └── push │ ├── Application.java │ ├── config │ ├── KafkaConfig.java │ ├── MqttConfig.java │ └── RedisConfig.java │ ├── controller │ ├── PushController.java │ ├── RegisterController.java │ └── SubController.java │ ├── dto │ ├── BaseMsgDto.java │ ├── PushMsgDto.java │ ├── RegistDto.java │ └── SubMsgDto.java │ ├── exception │ └── PushException.java │ ├── mqtt │ ├── MattConsumer.java │ └── MqttCallBack.java │ └── utils │ └── JsonUtils.java └── resources ├── application.yml └── logback.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /build/ 3 | *#*# 4 | *.#* 5 | *.iml 6 | *.ipr 7 | *.iws 8 | *.pyc 9 | *.pyo 10 | *.swp 11 | *~ 12 | .class 13 | .DS_Store 14 | .cache 15 | .classpath 16 | .ensime 17 | .ensime_cache/ 18 | .ensime_lucene 19 | .generated-mima* 20 | .idea/ 21 | .idea_modules/ 22 | .project 23 | .pydevproject 24 | .scala_dependencies 25 | .settings 26 | -------------------------------------------------------------------------------- /.gradle/3.5/file-changes/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gradle/3.5/taskHistory/taskHistory.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yidadi/push-server/6601de8ee08c28a166b7f357d14eb693c3139fff/.gradle/3.5/taskHistory/taskHistory.lock -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/built.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yidadi/push-server/6601de8ee08c28a166b7f357d14eb693c3139fff/.gradle/buildOutputCleanup/built.bin -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/cache.properties: -------------------------------------------------------------------------------- 1 | #Fri Sep 01 16:11:15 CST 2017 2 | gradle.version=3.5 3 | -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/cache.properties.lock: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 1、主要是基于mqtt的消息推送服务,本系统的设计采用springboot+mqtt来实现消息推送 2 | 2、采用kafka作为数据获取后暂存点,可以通过接口获取数据(sub),或则通过客户端发送到mqtt订阅的方式获取对应的消息 3 | 3、消息传输格式采用json,内部定义了一些常用的消息作为本服务的一个约束 4 | 4、需要搭建mqtt服务器,集群或则单机,具体搭建需要参考mqtt 5 | 5、这边项目还需要redis作为缓存工具,主要是缓存用户的发送信息 6 | 7 | @RestController 8 | @RequestMapping("/api/push-server/") 9 | public class RegisterController { 10 | @Autowired 11 | private RedisTemplate redisTemplate; 12 | 13 | /** 14 | * 进行注册 15 | */ 16 | @RequestMapping(value = "unRegist",method = RequestMethod.POST) 17 | public void unRegist(RegistDto registDto){ 18 | redisTemplate.boundSetOps(registDto.getTopicPre()).add(registDto.getMark()); 19 | } 20 | 21 | /** 22 | * 取消注册 23 | * @param registDto 24 | */ 25 | @RequestMapping(value = "regist",method = RequestMethod.POST) 26 | public void regist(RegistDto registDto){ 27 | redisTemplate.boundSetOps(registDto.getTopicPre()).remove(registDto.getMark()); 28 | } 29 | } 30 | 进行对应的订阅渠道注册,主要是消息推送的时候能针对性的推送 31 | 32 | /** 33 | * @Auther yidadi 34 | * @Date 17-9-1 下午4:31 35 | */ 36 | @RestController 37 | @RequestMapping("/api/push-server/") 38 | public class PushController { 39 | @Autowired 40 | private RedisTemplate redisTemplate; 41 | @Autowired 42 | private MqttClient mqttProducer; 43 | 44 | /** 45 | * 46 | * @param pushMsgDto 47 | */ 48 | @RequestMapping(value = "pushTopic",method = RequestMethod.POST) 49 | public void pushTopic(PushMsgDto pushMsgDto){ 50 | Set datas = redisTemplate.boundSetOps(pushMsgDto.getTopicPre()).members(); 51 | if(datas.isEmpty()){ 52 | throw new PushException("the register user is empty"); 53 | }else{ 54 | datas.forEach(data->{ 55 | MqttMessage message = new MqttMessage(); 56 | message.setQos(pushMsgDto.getQos()); 57 | message.setRetained(false); 58 | message.setPayload(pushMsgDto.getContent().getBytes()); 59 | try { 60 | mqttProducer.publish(pushMsgDto.getTopicPre().concat(data),message); 61 | } catch (MqttException e) { 62 | e.printStackTrace(); 63 | } 64 | }); 65 | } 66 | } 67 | 68 | /** 69 | * 70 | * @param pushMsgDto 71 | */ 72 | @RequestMapping(value = "pushOne",method = RequestMethod.POST) 73 | public void pushOne(PushMsgDto pushMsgDto){ 74 | MqttMessage message = new MqttMessage(); 75 | message.setQos(pushMsgDto.getQos()); 76 | message.setRetained(false); 77 | message.setPayload(pushMsgDto.getContent().getBytes()); 78 | try { 79 | mqttProducer.publish(pushMsgDto.getTopicPre().concat(pushMsgDto.getMark()),message); 80 | } catch (MqttException e) { 81 | e.printStackTrace(); 82 | } 83 | } 84 | } 85 | 86 | 可以直接调用接口的方式发送推送消息,可以单点推送也可针对对应的渠道推送 87 | 88 | 89 | /** 90 | * @Auther yidadi 91 | * @Date 17-9-4 下午3:42 92 | */ 93 | @RestController 94 | @RequestMapping("/api/push-server/") 95 | public class SubController { 96 | @Autowired 97 | private KafkaProducer kafkaProducer; 98 | 99 | /** 100 | * 101 | * @param subMsgDto 102 | */ 103 | @RequestMapping(value = "sub",method = RequestMethod.POST) 104 | public void sub(SubMsgDto subMsgDto){ 105 | ProducerRecord producerRecord = new ProducerRecord(subMsgDto.getMqtopic(), JsonUtils.toJson(subMsgDto)); 106 | kafkaProducer.send(producerRecord); 107 | } 108 | } 109 | 可以通过接口方式的获取客户端发送回来的数据 110 | 111 | 112 | 113 | 114 | /** 115 | * @Auther yidadi 116 | * @Date 17-9-4 下午3:38 117 | */ 118 | public class MqttCallBack implements MqttCallback { 119 | private KafkaProducer kafkaProducer; 120 | 121 | public MqttCallBack(KafkaProducer kafkaProducer) { 122 | this.kafkaProducer = kafkaProducer; 123 | } 124 | 125 | public void connectionLost(Throwable cause) { 126 | cause.printStackTrace(); 127 | } 128 | 129 | @Override 130 | public void messageArrived(String topic, MqttMessage message) throws Exception { 131 | SubMsgDto subMsgDto = (SubMsgDto)JsonUtils.readFromJson(new String(message.getPayload()),SubMsgDto.class); 132 | kafkaProducer.send(new ProducerRecord(subMsgDto.getMqtopic(),JsonUtils.toJson(subMsgDto))); 133 | } 134 | 135 | @Override 136 | public void deliveryComplete(IMqttDeliveryToken token) { 137 | 138 | } 139 | } 140 | 141 | 也可以通过mqtt的方式获取对应的渠道消息发送到kafka,消息体里面需要制定对应的kafka的topic 142 | 143 | 144 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.even' 2 | version '1.0-SNAPSHOT' 3 | 4 | apply plugin: 'java' 5 | 6 | sourceCompatibility = 1.8 7 | 8 | repositories { 9 | mavenLocal() 10 | maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } 11 | mavenCentral() 12 | } 13 | 14 | dependencies { 15 | compile group: 'com.alibaba', name: 'fastjson', version: '1.2.38' 16 | 17 | compile group: 'org.apache.kafka', name: 'kafka-clients', version: '0.11.0.0' 18 | compile group: 'org.eclipse.paho', name: 'org.eclipse.paho.client.mqttv3', version: '1.2.0' 19 | compile("org.springframework.boot:spring-boot-starter-web:1.5.6.RELEASE") 20 | compile group: 'org.springframework.boot', name: 'spring-boot-starter-redis', version: '1.4.7.RELEASE' 21 | testCompile group: 'junit', name: 'junit', version: '4.12' 22 | } 23 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'push-server' 2 | 3 | -------------------------------------------------------------------------------- /src/main/java/com/even/push/Application.java: -------------------------------------------------------------------------------- 1 | package com.even.push; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication(scanBasePackages = "com.even") 7 | public class Application { 8 | public static void main(String[] args) { 9 | SpringApplication.run(Application.class, args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/even/push/config/KafkaConfig.java: -------------------------------------------------------------------------------- 1 | package com.even.push.config; 2 | 3 | import org.apache.kafka.clients.producer.KafkaProducer; 4 | import org.apache.kafka.clients.producer.Producer; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | import java.util.Properties; 10 | 11 | /** 12 | * @Auther yidadi 13 | * @Date 17-9-4 下午3:49 14 | */ 15 | @Configuration 16 | public class KafkaConfig { 17 | @Value("${com.even.kafka.servers}") 18 | private String KafkaServers; 19 | 20 | @Bean 21 | public KafkaProducer kafkaProducer(){ 22 | Properties props = new Properties(); 23 | props.put("bootstrap.servers", KafkaServers); 24 | props.put("acks", "all"); 25 | props.put("retries", 0); 26 | props.put("batch.size", 16384); 27 | props.put("linger.ms", 1); 28 | props.put("buffer.memory", 33554432); 29 | props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); 30 | props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); 31 | return new KafkaProducer<>(props); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/even/push/config/MqttConfig.java: -------------------------------------------------------------------------------- 1 | package com.even.push.config; 2 | 3 | import org.eclipse.paho.client.mqttv3.MqttClient; 4 | import org.eclipse.paho.client.mqttv3.MqttConnectOptions; 5 | import org.eclipse.paho.client.mqttv3.MqttException; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | import java.util.UUID; 11 | 12 | /** 13 | * @Auther yidadi 14 | * @Date 17-9-1 下午4:38 15 | */ 16 | @Configuration 17 | public class MqttConfig { 18 | @Value("${com.even.mqtt.userName}") 19 | private String userName; 20 | @Value("${com.even.mqtt.passWord}") 21 | private String passWord; 22 | @Value("${com.even.mqtt.host}") 23 | private String host; 24 | @Bean 25 | public MqttClient mqttClient() throws MqttException { 26 | MqttClient mqttClient = new MqttClient(host, UUID.randomUUID().toString()); 27 | MqttConnectOptions options = new MqttConnectOptions(); 28 | options.setCleanSession(true); 29 | options.setUserName(userName); 30 | options.setPassword(passWord.toCharArray()); 31 | // 设置超时时间 32 | options.setConnectionTimeout(10); 33 | // 设置会话心跳时间 34 | options.setKeepAliveInterval(20); 35 | mqttClient.connect(options); 36 | return mqttClient; 37 | } 38 | 39 | 40 | /** 41 | * 42 | * @return 43 | * @throws MqttException 44 | */ 45 | @Bean 46 | public MqttClient mqttProducer() throws MqttException { 47 | MqttClient mqttProducer = new MqttClient(host, UUID.randomUUID().toString()); 48 | MqttConnectOptions options = new MqttConnectOptions(); 49 | options.setCleanSession(true); 50 | options.setUserName(userName); 51 | options.setPassword(passWord.toCharArray()); 52 | // 设置超时时间 53 | options.setConnectionTimeout(10); 54 | // 设置会话心跳时间 55 | options.setKeepAliveInterval(20); 56 | mqttProducer.connect(options); 57 | return mqttProducer; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/even/push/config/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.even.push.config; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.core.env.MapPropertySource; 6 | import org.springframework.data.redis.connection.RedisClusterConfiguration; 7 | import org.springframework.data.redis.connection.jedis.JedisClusterConnection; 8 | import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; 9 | import org.springframework.data.redis.core.RedisTemplate; 10 | import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; 11 | import org.springframework.data.redis.serializer.StringRedisSerializer; 12 | 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * @Auther yidadi 18 | * @Date 17-9-7 下午2:21 19 | */ 20 | public class RedisConfig { 21 | @Value("${com.even.redis.nodes}") 22 | private String clusterNodes; 23 | 24 | @Value("${com.even.redis.timeout}") 25 | private Long timeout; 26 | 27 | @Value("${com.even.redis.max-redirects}") 28 | private int redirects; 29 | 30 | @Bean 31 | public RedisClusterConfiguration getClusterConfiguration() { 32 | 33 | Map source = new HashMap(); 34 | source.put("spring.redis.cluster.nodes", clusterNodes); 35 | source.put("spring.redis.cluster.timeout", timeout); 36 | source.put("spring.redis.cluster.max-redirects", redirects); 37 | return new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration", source)); 38 | 39 | } 40 | 41 | @Bean 42 | public JedisConnectionFactory getConnectionFactory() { 43 | return new JedisConnectionFactory(getClusterConfiguration()); 44 | } 45 | 46 | @Bean 47 | public JedisClusterConnection getJedisClusterConnection() { 48 | return (JedisClusterConnection) getConnectionFactory().getConnection(); 49 | 50 | } 51 | 52 | @Bean 53 | public RedisTemplate getRedisTemplate() { 54 | RedisTemplate clusterTemplate = new RedisTemplate(); 55 | clusterTemplate.setConnectionFactory(getConnectionFactory()); 56 | clusterTemplate.setKeySerializer(new StringRedisSerializer()); 57 | clusterTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer()); 58 | return clusterTemplate; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/even/push/controller/PushController.java: -------------------------------------------------------------------------------- 1 | package com.even.push.controller; 2 | 3 | import com.even.push.dto.PushMsgDto; 4 | import com.even.push.exception.PushException; 5 | import org.eclipse.paho.client.mqttv3.MqttClient; 6 | import org.eclipse.paho.client.mqttv3.MqttException; 7 | import org.eclipse.paho.client.mqttv3.MqttMessage; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.data.redis.core.RedisTemplate; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RequestMethod; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | import java.util.Set; 15 | 16 | /** 17 | * @Auther yidadi 18 | * @Date 17-9-1 下午4:31 19 | */ 20 | @RestController 21 | @RequestMapping("/api/push-server/") 22 | public class PushController { 23 | @Autowired 24 | private RedisTemplate redisTemplate; 25 | @Autowired 26 | private MqttClient mqttProducer; 27 | 28 | /** 29 | * 30 | * @param pushMsgDto 31 | */ 32 | @RequestMapping(value = "pushTopic",method = RequestMethod.POST) 33 | public void pushTopic(PushMsgDto pushMsgDto){ 34 | Set datas = redisTemplate.boundSetOps(pushMsgDto.getTopicPre()).members(); 35 | if(datas.isEmpty()){ 36 | throw new PushException("the register user is empty"); 37 | }else{ 38 | datas.forEach(data->{ 39 | MqttMessage message = new MqttMessage(); 40 | message.setQos(pushMsgDto.getQos()); 41 | message.setRetained(false); 42 | message.setPayload(pushMsgDto.getContent().getBytes()); 43 | try { 44 | mqttProducer.publish(pushMsgDto.getTopicPre().concat(data),message); 45 | } catch (MqttException e) { 46 | e.printStackTrace(); 47 | } 48 | }); 49 | } 50 | } 51 | 52 | /** 53 | * 54 | * @param pushMsgDto 55 | */ 56 | @RequestMapping(value = "pushOne",method = RequestMethod.POST) 57 | public void pushOne(PushMsgDto pushMsgDto){ 58 | MqttMessage message = new MqttMessage(); 59 | message.setQos(pushMsgDto.getQos()); 60 | message.setRetained(false); 61 | message.setPayload(pushMsgDto.getContent().getBytes()); 62 | try { 63 | mqttProducer.publish(pushMsgDto.getTopicPre().concat(pushMsgDto.getMark()),message); 64 | } catch (MqttException e) { 65 | e.printStackTrace(); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/even/push/controller/RegisterController.java: -------------------------------------------------------------------------------- 1 | package com.even.push.controller; 2 | 3 | 4 | import com.even.push.dto.RegistDto; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.data.redis.core.RedisTemplate; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | @RestController 12 | @RequestMapping("/api/push-server/") 13 | public class RegisterController { 14 | @Autowired 15 | private RedisTemplate redisTemplate; 16 | 17 | /** 18 | * 进行注册 19 | */ 20 | @RequestMapping(value = "unRegist",method = RequestMethod.POST) 21 | public void unRegist(RegistDto registDto){ 22 | redisTemplate.boundSetOps(registDto.getTopicPre()).add(registDto.getMark()); 23 | } 24 | 25 | /** 26 | * 取消注册 27 | * @param registDto 28 | */ 29 | @RequestMapping(value = "regist",method = RequestMethod.POST) 30 | public void regist(RegistDto registDto){ 31 | redisTemplate.boundSetOps(registDto.getTopicPre()).remove(registDto.getMark()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/even/push/controller/SubController.java: -------------------------------------------------------------------------------- 1 | package com.even.push.controller; 2 | 3 | import com.even.push.dto.SubMsgDto; 4 | import com.even.push.utils.JsonUtils; 5 | import org.apache.kafka.clients.producer.KafkaProducer; 6 | import org.apache.kafka.clients.producer.ProducerRecord; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | /** 13 | * @Auther yidadi 14 | * @Date 17-9-4 下午3:42 15 | */ 16 | @RestController 17 | @RequestMapping("/api/push-server/") 18 | public class SubController { 19 | @Autowired 20 | private KafkaProducer kafkaProducer; 21 | 22 | /** 23 | * 24 | * @param subMsgDto 25 | */ 26 | @RequestMapping(value = "sub",method = RequestMethod.POST) 27 | public void sub(SubMsgDto subMsgDto){ 28 | ProducerRecord producerRecord = new ProducerRecord(subMsgDto.getMqtopic(), JsonUtils.toJson(subMsgDto)); 29 | kafkaProducer.send(producerRecord); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/even/push/dto/BaseMsgDto.java: -------------------------------------------------------------------------------- 1 | package com.even.push.dto; 2 | 3 | /** 4 | * @Auther yidadi 5 | * @Date 17-9-1 下午4:48 6 | */ 7 | public class BaseMsgDto { 8 | /**注册订阅的topic的前缀*/ 9 | private String topicPre; 10 | 11 | public String getTopicPre() { 12 | return topicPre; 13 | } 14 | 15 | public void setTopicPre(String topicPre) { 16 | this.topicPre = topicPre; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/even/push/dto/PushMsgDto.java: -------------------------------------------------------------------------------- 1 | package com.even.push.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @Auther yidadi 7 | * @Date 17-9-1 下午4:32 8 | */ 9 | public class PushMsgDto extends BaseMsgDto implements Serializable{ 10 | private static final long serialVersionUID = -1432275044516236784L; 11 | /**消息体内容 格式自己约定*/ 12 | private String content; 13 | /**消息的投递次数 0 1 2*/ 14 | private int qos; 15 | /**自己的标示*/ 16 | private String mark; 17 | 18 | public String getContent() { 19 | return content; 20 | } 21 | 22 | public void setContent(String content) { 23 | this.content = content; 24 | } 25 | 26 | public int getQos() { 27 | return qos; 28 | } 29 | 30 | public void setQos(int qos) { 31 | this.qos = qos; 32 | } 33 | 34 | public String getMark() { 35 | return mark; 36 | } 37 | 38 | public void setMark(String mark) { 39 | this.mark = mark; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/even/push/dto/RegistDto.java: -------------------------------------------------------------------------------- 1 | package com.even.push.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @Auther yidadi 7 | * @Date 17-9-1 下午4:24 8 | */ 9 | public class RegistDto extends BaseMsgDto implements Serializable{ 10 | private static final long serialVersionUID = 7229390832544360153L; 11 | /**自己的标示*/ 12 | private String mark; 13 | 14 | public String getMark() { 15 | return mark; 16 | } 17 | 18 | public void setMark(String mark) { 19 | this.mark = mark; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/even/push/dto/SubMsgDto.java: -------------------------------------------------------------------------------- 1 | package com.even.push.dto; 2 | 3 | /** 4 | * @Auther yidadi 5 | * @Date 17-9-4 下午3:40 6 | */ 7 | public class SubMsgDto extends BaseMsgDto{ 8 | private String Mqtopic; 9 | private String content; 10 | private String mark; 11 | /**消息的投递次数 0 1 2*/ 12 | private int qos; 13 | 14 | public String getMqtopic() { 15 | return Mqtopic; 16 | } 17 | 18 | public void setMqtopic(String mqtopic) { 19 | Mqtopic = mqtopic; 20 | } 21 | 22 | public String getContent() { 23 | return content; 24 | } 25 | 26 | public void setContent(String content) { 27 | this.content = content; 28 | } 29 | 30 | public String getMark() { 31 | return mark; 32 | } 33 | 34 | public void setMark(String mark) { 35 | this.mark = mark; 36 | } 37 | 38 | public int getQos() { 39 | return qos; 40 | } 41 | 42 | public void setQos(int qos) { 43 | this.qos = qos; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/even/push/exception/PushException.java: -------------------------------------------------------------------------------- 1 | package com.even.push.exception; 2 | 3 | /** 4 | * @Auther yidadi 5 | * @Date 17-9-1 下午4:36 6 | */ 7 | public class PushException extends RuntimeException{ 8 | public PushException(String message) { 9 | super(message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/even/push/mqtt/MattConsumer.java: -------------------------------------------------------------------------------- 1 | package com.even.push.mqtt; 2 | 3 | import org.apache.kafka.clients.producer.KafkaProducer; 4 | import org.eclipse.paho.client.mqttv3.MqttClient; 5 | import org.eclipse.paho.client.mqttv3.MqttException; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | 8 | /** 9 | * @Auther yidadi 10 | * @Date 17-9-1 下午4:52 11 | */ 12 | 13 | public class MattConsumer { 14 | @Autowired 15 | private MqttClient mqttClient; 16 | 17 | @Autowired 18 | private KafkaProducer kafkaProducer; 19 | 20 | private static final String TOPIC = "com/even/sub"; 21 | private static final Integer QOS = 1; 22 | 23 | 24 | public void sub() throws MqttException { 25 | mqttClient.subscribe(TOPIC,QOS); 26 | mqttClient.setCallback(new MqttCallBack(kafkaProducer)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/even/push/mqtt/MqttCallBack.java: -------------------------------------------------------------------------------- 1 | package com.even.push.mqtt; 2 | 3 | import com.even.push.dto.SubMsgDto; 4 | import com.even.push.utils.JsonUtils; 5 | import org.apache.kafka.clients.producer.KafkaProducer; 6 | import org.apache.kafka.clients.producer.ProducerRecord; 7 | import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; 8 | import org.eclipse.paho.client.mqttv3.MqttCallback; 9 | import org.eclipse.paho.client.mqttv3.MqttMessage; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | 12 | /** 13 | * @Auther yidadi 14 | * @Date 17-9-4 下午3:38 15 | */ 16 | public class MqttCallBack implements MqttCallback { 17 | private KafkaProducer kafkaProducer; 18 | 19 | public MqttCallBack(KafkaProducer kafkaProducer) { 20 | this.kafkaProducer = kafkaProducer; 21 | } 22 | 23 | public void connectionLost(Throwable cause) { 24 | cause.printStackTrace(); 25 | } 26 | 27 | @Override 28 | public void messageArrived(String topic, MqttMessage message) throws Exception { 29 | SubMsgDto subMsgDto = (SubMsgDto)JsonUtils.readFromJson(new String(message.getPayload()),SubMsgDto.class); 30 | kafkaProducer.send(new ProducerRecord(subMsgDto.getMqtopic(),JsonUtils.toJson(subMsgDto))); 31 | } 32 | 33 | @Override 34 | public void deliveryComplete(IMqttDeliveryToken token) { 35 | 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/java/com/even/push/utils/JsonUtils.java: -------------------------------------------------------------------------------- 1 | package com.even.push.utils; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | 5 | /** 6 | * @Auther yidadi 7 | * @Date 17-9-4 下午4:07 8 | */ 9 | public class JsonUtils { 10 | 11 | /** 12 | * 13 | * @param data 14 | * @param type 15 | * @return 16 | */ 17 | public static Object readFromJson(String data,Class type) { 18 | return JSON.parseObject(data,type); 19 | } 20 | 21 | /** 22 | * 23 | * @param obj 24 | * @return 25 | */ 26 | public static String toJson(Object obj) { 27 | return JSON.toJSONString(obj); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9001 3 | com: 4 | even: 5 | mqtt: 6 | userName: guest 7 | passWord: guest 8 | host: tcp://192.168.36.102:1883 #采用集群后这选择用master作为数据的订阅点 9 | kafka: 10 | servers: 127.0.0.1:9002,127.0.0.1:9003,127.0.0.1:9004 11 | redis: 12 | nodes: 127.0.0.1:6379,127.0.0.1:6378 13 | timeOut: 6000 14 | maxRedirects: 3 -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 10 | 11 | 12 | 13 | 14 | 15 | 16 | ${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log 17 | 18 | 30 19 | 20 | 21 | 22 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 23 | 24 | 25 | 26 | 10MB 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | --------------------------------------------------------------------------------