展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

springboot整合mqtt

单个username认证

  • yml配置
mqtt:
  broker-url: tcp://192.168.96.168:1883
  client-id: emq-client
  username: user
  password: 123456
  • EmqClient
@Component
public class EmqClient {
    
    private static final Logger log = LoggerFactory.getLogger(EmqClient.class);

    private IMqttClient mqttClient;
    
    @Autowired
    private MqttProperties mqttProperties;
    
    @Autowired
    private MqttCallback mqttCallback;
    
    @PostConstruct
    public void init(){
        MqttClientPersistence mempersitence = new MemoryPersistence();
        try {
            mqttClient = new MqttClient(mqttProperties.getBrokerUrl(),mqttProperties.getClientId(),mempersitence);
        } catch (MqttException e) {
            log.error("初始化客户端mqttClient对象失败,errormsg={},brokerUrl={},clientId={}",e.getMessage(),mqttProperties.getBrokerUrl(),mqttProperties.getClientId());
        }
    }

    /**
     * 连接broker
     * @param username
     * @param password
     */
    public void connect(String username,String password){
        MqttConnectOptions options = new MqttConnectOptions();
        options.setAutomaticReconnect(true);
        options.setUserName(username);
        options.setPassword(password.toCharArray());
        options.setCleanSession(true);
        mqttClient.setCallback(mqttCallback);
        try {
            mqttClient.connect(options);
        } catch (MqttException e) {
            log.error("mqtt客户端连接服务端失败,失败原因{}",e.getMessage());
        }
    }

    /**
     * 断开连接
     */
    @PreDestroy
    public void disConnect(){
        try {
            mqttClient.disconnect();
        } catch (MqttException e) {
            log.error("断开连接产生异常,异常信息{}",e.getMessage());
        }
    }

    /**
     * 重连
     */
    public void reConnect(){
        try {
            mqttClient.reconnect();
        } catch (MqttException e) {
            log.error("重连失败,失败原因{}",e.getMessage());
        }
    }

    /**
     * 发布消息
     * @param topic
     * @param msg
     * @param qos
     * @param retain
     */
    public void publish(String topic, String msg, QosEnum qos, boolean retain){
        MqttMessage mqttMessage = new MqttMessage();
        mqttMessage.setPayload(msg.getBytes());
        mqttMessage.setQos(qos.value());
        mqttMessage.setRetained(retain);
        try {
            mqttClient.publish(topic,mqttMessage);
        } catch (MqttException e) {
            log.error("发布消息失败,errormsg={},topic={},msg={},qos={},retain={}",e.getMessage(),topic,msg,qos.value(),retain);
        }
    }

    /**
     * 订阅
     * @param topicFilter
     * @param qos
     */
    public void subscribe(String topicFilter,QosEnum qos){
        try {
            mqttClient.subscribe(topicFilter,qos.value());
        } catch (MqttException e) {
            log.error("订阅主题失败,errormsg={},topicFilter={},qos={}",e.getMessage(),topicFilter,qos.value());
        }
    }

    /**
     * 取消订阅
     * @param topicFilter
     */
    public void unSubscribe(String topicFilter){
        try {
            mqttClient.unsubscribe(topicFilter);
        } catch (MqttException e) {
            log.error("取消订阅失败,errormsg={},topicfiler={}",e.getMessage(),topicFilter);
        }
    }
    
}
  • MessageCallback
@Component
public class MessageCallback implements MqttCallback {
    
    private static final Logger log = LoggerFactory.getLogger(MessageCallback.class);

    /**
     * 丢失了对服务端的连接后触发的回调
     * @param cause
     */
    @Override
    public void connectionLost(Throwable cause) {
        // 资源的清理  重连
        log.info("丢失了对服务端的连接");
    }

    /**
     * 应用收到消息后触发的回调
     * @param topic
     * @param message
     * @throws Exception
     */
    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        log.info("订阅者订阅到了消息,topic={},messageid={},qos={},payload={}",
                topic,
                message.getId(),
                message.getQos(),
                new String(message.getPayload()));
    }

    /**
     * 消息发布者消息发布完成产生的回调
     * @param token
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        int messageId = token.getMessageId();
        String[] topics = token.getTopics();
        log.info("消息发布完成,messageid={},topics={}",messageId,topics);
    }

}
  • QosEnum
public enum QosEnum {

    QoS0(0),QoS1(1),QoS2(2);

    private final int value;

    QosEnum(int value) {
        this.value = value;
    }
    
    public int value(){
        return this.value;
    }

}
  • MqttProperties
@Component
@Configuration
@ConfigurationProperties(prefix = "mqtt")
public class MqttProperties {
    
    private String brokerUrl;
    
    private String clientId;
    
    private String username;
    
    private String password;

    public String getBrokerUrl() {
        return brokerUrl;
    }

    public void setBrokerUrl(String brokerUrl) {
        this.brokerUrl = brokerUrl;
    }

    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "MqttProperties{" +
                "brokerUrl='" + brokerUrl + '\'' +
                ", clientId='" + clientId + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

}
  • MqttInitMsgUtil
@Component
@Slf4j
public class MqttInitMsgUtil {

    @Resource
    private MqttInitUtil mqttInitUtil;

    @Resource
    private PlatFormSystemMessageService platFormSystemMessageService;

    private static MqttInitMsgUtil mqttInitMsgUtil;

    @PostConstruct
    public void init(){
        mqttInitMsgUtil = this;
        mqttInitMsgUtil.mqttInitUtil = this.mqttInitUtil;
    }

    /**
     * 发送消息
     * templateId 模板id
     * pubId 订阅者id
     * userType 订阅者用户类型
     * @throws Exception
     */
    public void sendMqttMsg(String templateId, String pubId, String userType) {
        try {
            // 拼接消息主题
            StringBuffer result = new StringBuffer();
            result.append("testtopic");
            result.append("/");
            result.append(pubId);
            // 获取消息模板
            TMessageTemplate tMessageTemplate = platFormSystemMessageService.queryTMessageTemplate(templateId);
            Map<String,String> map = new HashMap<String,String>();
            map.put("msgTemplateTitle",tMessageTemplate.getMsgTemplateTitle());
            map.put("templateContent",tMessageTemplate.getTemplateContent());
            String str = ConverUitl.getMapToString(map);
            // 发布消息
            mqttInitUtil.publish(result.toString(), str, QosEnum.QoS2,false);
            // 存入历史记录表
            TMessage tMessage = new TMessage();
            tMessage.setId(SnowflakeIdWorkerUtil.nextId());
            tMessage.setCreated(new Date());
            tMessage.setUpdated(new Date());
            tMessage.setReadStatus("1");  // 设置为未读
            tMessage.setMsgTitle(map.get("msgTemplateTitle"));
            tMessage.setMsgContent(map.get("templateContent"));
            tMessage.setUserType(userType);  // 接收者类型
            tMessage.setUserId(pubId);  // 接收者主键
            tMessage.setMtId(templateId);  // 关联的模板id
            tMessage.setDeleted(0);
            platFormSystemMessageService.addTMessage(tMessage);
        }catch (Exception e){
            log.error(e.getMessage());
            throw new GlobalException(e.getMessage());
        }
    }

}
  • 测试
@RestController
@RequestMapping("/tMessageTest")
@AllArgsConstructor
@Api(tags = "消息通知测试")
public class TMessageTest {

    @Autowired
    private EmqClient emqClient;

    @Autowired
    private MqttProperties properties;

    @Autowired
    private MsgPubMqttUtil msgPubMqttUtil;

    @Autowired
    private MqttInitUtil mqttInitUtil;

    @Autowired
    private MqttInitMsgUtil mqttInitMsgUtil;

    /**
     * 发布通知案例测试
     * 参数为:消息模板id,消息订阅者id,订阅者用户类型
     */
    @RequestMapping("/test1")
    @ResponseBody
    public String test1(){
        msgPubMqttUtil.sendMqttMessage("955407201726365696", "951524255252611072", TMessageUserTypeEnum.USER.getValue());
        return "success";
    }

}

多个username认证

  • yml配置
mqtt:
  broker-url: tcp://192.168.96.168:1883
  client-id: emq-client
  username: user
  password: 123456
  authurl: http://192.168.96.168:8081/api/v4/auth_username/
  authname: admin
  authpwd: public
  • MqttInitUtil
@Component
public class MqttInitUtil {

    public static String authurl;

    public static String authname;

    public static String authpwd;

    @Value("${mqtt.authurl}")
    public void setAuthurl(String authurl) {
        MqttInitUtil.authurl = authurl;
    }

    @Value("${mqtt.authname}")
    public void setAuthname(String authname) {
        MqttInitUtil.authname = authname;
    }

    @Value("${mqtt.authpwd}")
    public void setAuthpwd(String authpwd) {
        MqttInitUtil.authpwd = authpwd;
    }

    private static final Logger log = LoggerFactory.getLogger(EmqClient.class);

    private IMqttClient mqttClient;

    @Autowired
    private MqttProperties mqttProperties;

    @Autowired
    private MqttCallback mqttCallback;

    /**
     * 创建emqx对象
     * 连接服务器
     * @param emqUser 自定义的用户名
     * @param emqPwd  自定义的密码
     * @throws IOException
     */
    public void createEmqxUser(String emqUser, String emqPwd, String clientId) throws IOException {
        // 创建emqx连接用户
        String url = authurl;
        String token = authname + ":" + authpwd;
        Map<String, String> prarms = new HashMap<>();
        prarms.put("username",emqUser);
        prarms.put("password", emqPwd);
        String jsonPrarms = JSON.toJSONString(prarms);
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();   //获取浏览器信息
        HttpPost httpPost = new HttpPost(url);
        String encoding = DatatypeConverter.printBase64Binary(token.getBytes("UTF-8"));  //username  password 自行修改  中间":"不可少
        httpPost.setHeader("Authorization", "Basic " + encoding);
        HttpEntity entityParam = new StringEntity(jsonPrarms, ContentType.create("application/json", "UTF-8"));  //这里的“application/json” 可以更换因为本人是传的json参数所以用的这个
        httpPost.setEntity(entityParam);     //把参数添加到post请求
        HttpResponse response = httpClient.execute(httpPost);
        StatusLine statusLine = response.getStatusLine();   //获取请求对象中的响应行对象
        int responseCode = statusLine.getStatusCode();
        if (responseCode == 200) {
            //获取响应信息
            HttpEntity entity = response.getEntity();
            InputStream input = entity.getContent();
            BufferedReader br = new BufferedReader(new InputStreamReader(input,"utf-8"));
            String str1 = br.readLine();
            System.out.println("服务器的响应是:" + str1);
            br.close();
            input.close();
        } else {
            System.out.println("响应失败");
        }
        // 初始化
        init(clientId);
        // 连接
        connect(emqUser,emqPwd);
        // end
    }

    /**
     * 删除emqx 对象
     * @param emqUser
     * @throws IOException
     */
    public String delEmqxUser(String emqUser) throws IOException {
        String url = authurl + emqUser;
        String token = authname + ":" + authpwd;
        String encoding = DatatypeConverter.printBase64Binary(token.getBytes("UTF-8"));
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpDelete httpDelete = new HttpDelete(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000).setConnectionRequestTimeout(35000).setSocketTimeout(60000).build();
        httpDelete.setConfig(requestConfig);
        httpDelete.setHeader("Content-type", "application/json");
        httpDelete.setHeader("DataEncoding", "UTF-8");
        httpDelete.setHeader("Authorization", "Basic " + encoding);
        CloseableHttpResponse httpResponse = null;
        try {
            httpResponse = httpClient.execute(httpDelete);
            HttpEntity entity = httpResponse.getEntity();
            String result = EntityUtils.toString(entity);
            return result;
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /***
     * 初始化
     * @param clientId
     */
    //@PostConstruct
    public void init(String clientId){
        MqttClientPersistence mempersitence = new MemoryPersistence();
        try {
            mqttClient = new MqttClient(mqttProperties.getBrokerUrl(),clientId,mempersitence);
        } catch (MqttException e) {
            log.error("初始化客户端mqttClient对象失败,errormsg={},brokerUrl={},clientId={}",e.getMessage(),mqttProperties.getBrokerUrl(),clientId);
        }
    }
    /**
     * 连接broker
     * @param username
     * @param password
     */
    public void connect(String username,String password){
        MqttConnectOptions options = new MqttConnectOptions();
        options.setAutomaticReconnect(true);
        options.setUserName(username);
        options.setPassword(password.toCharArray());
        options.setCleanSession(true);
        mqttClient.setCallback(mqttCallback);
        try {
            mqttClient.connect(options);
        } catch (MqttException e) {
            log.error("mqtt客户端连接服务端失败,失败原因{}",e.getMessage());
        }
    }
    /**
     * 断开连接
     */
    //@PreDestroy
    public void disConnect(){
        try {
            mqttClient.disconnect();
        } catch (MqttException e) {
            log.error("断开连接产生异常,异常信息{}",e.getMessage());
        }
    }
    /**
     * 重连
     */
    public void reConnect(){
        try {
            mqttClient.reconnect();
        } catch (MqttException e) {
            log.error("重连失败,失败原因{}",e.getMessage());
        }
    }
    /**
     * 发布消息
     * @param topic
     * @param msg
     * @param qos
     * @param retain
     */
    public void publish(String topic, String msg, QosEnum qos, boolean retain){
        MqttMessage mqttMessage = new MqttMessage();
        mqttMessage.setPayload(msg.getBytes());
        mqttMessage.setQos(qos.value());
        mqttMessage.setRetained(retain);
        try {
            mqttClient.publish(topic,mqttMessage);
        } catch (MqttException e) {
            log.error("发布消息失败,errormsg={},topic={},msg={},qos={},retain={}",e.getMessage(),topic,msg,qos.value(),retain);
        }
    }
    /**
     * 订阅
     * @param topicFilter
     * @param qos
     */
    public void subscribe(String topicFilter,QosEnum qos){
        try {
            mqttClient.subscribe(topicFilter,qos.value());
        } catch (MqttException e) {
            log.error("订阅主题失败,errormsg={},topicFilter={},qos={}",e.getMessage(),topicFilter,qos.value());
        }
    }
    /**
     * 取消订阅
     * @param topicFilter
     */
    public void unSubscribe(String topicFilter){
        try {
            mqttClient.unsubscribe(topicFilter);
        } catch (MqttException e) {
            log.error("取消订阅失败,errormsg={},topicfiler={}",e.getMessage(),topicFilter);
        }
    }

}
  • MqttInitMsgUtil
@Component
@Slf4j
public class MqttInitMsgUtil {

    @Resource
    private MqttInitUtil mqttInitUtil;

    @Resource
    private PlatFormSystemMessageService platFormSystemMessageService;

    private static MqttInitMsgUtil mqttInitMsgUtil;

    @PostConstruct
    public void init(){
        mqttInitMsgUtil = this;
        mqttInitMsgUtil.mqttInitUtil = this.mqttInitUtil;
    }

    /**
     * 发送消息
     * templateId 模板id
     * pubId 订阅者id
     * userType 订阅者用户类型
     * @throws Exception
     */
    public void sendMqttMsg(String templateId, String pubId, String userType) {
        try {
            // 拼接消息主题
            StringBuffer result = new StringBuffer();
            result.append("testtopic");
            result.append("/");
            result.append(pubId);
            // 获取消息模板
            TMessageTemplate tMessageTemplate = platFormSystemMessageService.queryTMessageTemplate(templateId);
            Map<String,String> map = new HashMap<String,String>();
            map.put("msgTemplateTitle",tMessageTemplate.getMsgTemplateTitle());
            map.put("templateContent",tMessageTemplate.getTemplateContent());
            String str = ConverUitl.getMapToString(map);
            // 发布消息
            mqttInitUtil.publish(result.toString(), str, QosEnum.QoS2,false);
            // 存入历史记录表
            TMessage tMessage = new TMessage();
            tMessage.setId(SnowflakeIdWorkerUtil.nextId());
            tMessage.setCreated(new Date());
            tMessage.setUpdated(new Date());
            tMessage.setReadStatus("1");  // 设置为未读
            tMessage.setMsgTitle(map.get("msgTemplateTitle"));
            tMessage.setMsgContent(map.get("templateContent"));
            tMessage.setUserType(userType);  // 接收者类型
            tMessage.setUserId(pubId);  // 接收者主键
            tMessage.setMtId(templateId);  // 关联的模板id
            tMessage.setDeleted(0);
            platFormSystemMessageService.addTMessage(tMessage);
        }catch (Exception e){
            log.error(e.getMessage());
            throw new GlobalException(e.getMessage());
        }
    }

}
  • 测试
    /**
     * 传入的参数为自定义的用户名、密码、clientId
     * 调用方法创建新的连接用户
     * @return
     * @throws IOException
     */
    @RequestMapping("/test2")
    @ResponseBody
    public String test2() throws IOException {
        mqttInitUtil.createEmqxUser("goudan1", "goudan", "clientId_3239856123141");
        return "success";
    }

    /**
     * 发布消息
     * @return
     */
    @RequestMapping("/test3")
    @ResponseBody
    public String test3(){
        mqttInitMsgUtil.sendMqttMsg("955407201726365696", "951524255252611072", TMessageUserTypeEnum.USER.getValue());
        return "success";
    }

    /**
     * 断开连接
     * @return
     */
    @RequestMapping("/test4")
    @ResponseBody
    public String test4() throws IOException {
        mqttInitUtil.delEmqxUser("goudan1");
        return "success";
    }
posted @ 2022-04-02 19:39  DogLeftover  阅读(259)  评论(0编辑  收藏  举报