com.hp.message.config.MsgAutoConfigure Maven / Gradle / Ivy
package com.hp.message.config;
import com.alibaba.fastjson.JSON;
import com.hp.message.Constant;
import com.hp.message.domain.EmqxDataMsg;
import com.hp.message.enums.EmqxQosType;
import com.hp.message.enums.MsgType;
import com.hp.message.handler.ReceMessageHandler;
import com.hp.message.handler.SendMessageHandler;
import com.hp.message.interfaces.ISdkSendMsgService;
import com.hp.message.property.AppProperty;
import com.hp.message.property.MsgProperty;
import com.hp.message.interfaces.ISdkReceMsgService;
import com.hp.message.service.SdkReceMsgService;
import com.hp.message.service.SdkSendMsgService;
import com.hp.message.utils.MsgTopicUtil;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.dsl.context.IntegrationFlowContext;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
/**
* @author 尚肖磊
* @create 2021-06-24 18:11
* @Description: msg相关自动配置类
*/
@Slf4j
@Configuration
@AutoConfigureAfter(AppAutoConfigure.class)
@IntegrationComponentScan("com.hp.message")
@EnableConfigurationProperties(value = MsgProperty.class)
public class MsgAutoConfigure {
public static final String outboundChannelName = "mqttOutboundChannel";
/**
* 华普app相关配置类
*/
private AppProperty appProperty;
/**
* 华普消息服务配置类
*/
private final MsgProperty msgProperty;
@Autowired
private IntegrationFlowContext flowContext;
public MsgAutoConfigure(MsgProperty msgProperty, AppProperty appProperty) {
if (msgProperty == null){
log.error( "{} config lost", MsgProperty.DEFAULT_PREFIX);
}
this.msgProperty = msgProperty;
if (appProperty == null){
log.error( "{} config lost", AppProperty.DEFAULT_PREFIX);
}
this.appProperty = appProperty;
}
/**
* 配置mqttConnectOptions 对象
*
* @return
*/
@Bean
@ConditionalOnMissingBean
public MqttConnectOptions getMqttConnectOptions() {
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setCleanSession(true);
mqttConnectOptions.setUserName(appProperty.getAppId());
mqttConnectOptions.setPassword(appProperty.getAppKey().toCharArray());
mqttConnectOptions.setServerURIs(new String[]{msgProperty.getMsgHost()});
mqttConnectOptions.setConnectionTimeout(msgProperty.getConnectTimeout());
mqttConnectOptions.setKeepAliveInterval(msgProperty.getKeepAliveInterval());
mqttConnectOptions.setAutomaticReconnect(true);
return mqttConnectOptions;
}
/**
* mqtt client工厂对象
*
* @return
*/
@Bean
@ConditionalOnMissingBean
public MqttPahoClientFactory getMqttClientFactory() {
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
factory.setConnectionOptions(getMqttConnectOptions());
return factory;
}
/**
* mqtt client工厂对象
*
* @return
*/
public MqttPahoClientFactory getMqttClientFactoryWithWill() {
MqttPahoClientFactory mqttPahoClientFactory = getMqttClientFactory();
// 配置遗嘱消息
String topic = MsgTopicUtil.getAppPushTopic(appProperty.getAppId());
mqttPahoClientFactory
.getConnectionOptions()
.setWill(topic, getWillMesssage(), EmqxQosType.QOS_0.getQos(), false);
return mqttPahoClientFactory;
}
/**
* 构造 接收mqtt消息 对象
*
* @return
*/
@Bean
public MessageProducer mqttInbound() {
MqttPahoMessageDrivenChannelAdapter adapter
= new MqttPahoMessageDrivenChannelAdapter(getReceiverClientId(),
getMqttClientFactory());
// 设置默认订阅
adapter.addTopic(MsgTopicUtil.getAppDefaultSubTopic(appProperty.getAppId()), 0);
adapter.setRecoveryInterval(1000);
// 设置转换器,接收bytes
DefaultPahoMessageConverter converter = new DefaultPahoMessageConverter();
converter.setPayloadAsBytes(true);
adapter.setConverter(converter);
IntegrationFlow integrationFlow = IntegrationFlows
.from(adapter).handle(new ReceMessageHandler()).get();
flowContext.registration(integrationFlow).register();
return adapter;
}
/**
* 消息发送通道
*
* @return
*/
@Bean
public MessageChannel mqttOutboundChannel() {
return new DirectChannel();
}
@Bean
@ServiceActivator(inputChannel = outboundChannelName, autoStartup = "true")
public MessageHandler mqttOutbound() {
SendMessageHandler messageHandler
= new SendMessageHandler(getSenderClientId(), getMqttClientFactoryWithWill());
messageHandler.setAsync(true);
// 设置转换器,发送bytes
DefaultPahoMessageConverter converter = new DefaultPahoMessageConverter();
converter.setPayloadAsBytes(true);
messageHandler.setDefaultRetained(false);
messageHandler.setConverter(converter);
messageHandler.onInit();
return messageHandler;
}
/**
* 构造默认消息接收服务类
*
* @return
*/
@Bean
@ConditionalOnMissingBean
public ISdkReceMsgService createSdkReceMsService(){
return new SdkReceMsgService();
}
/**
* 构造消息发送服务类
*
* @return
*/
@Bean
@ConditionalOnMissingBean
public ISdkSendMsgService createSdkSendMsService(){
return new SdkSendMsgService();
}
/**
* 获取消费者 ClientId
*
* @return
*/
private String getReceiverClientId(){
String clientId = Constant.RECEIVER_CLIENTID_PREFIX;
clientId = clientId + System.currentTimeMillis();
return clientId;
}
/**
* 获取生产者 ClientId
*
* @return
*/
private String getSenderClientId() {
String clientId = Constant.SENDER_CLIENTID_PREFIX;
clientId = clientId + System.currentTimeMillis();
return clientId;
}
/**
* 获取遗嘱消息对象
*
* @return
*/
private byte[] getWillMesssage() {
EmqxDataMsg emqxDataMsg = new EmqxDataMsg();
emqxDataMsg.setMsgType(MsgType.SDK_OFFLINE.getMsgTypeId());
return JSON.toJSONBytes(emqxDataMsg);
}
}