免费做章子的网站/百度手机助手官方正版

免费做章子的网站,百度手机助手官方正版,河南省工程建设信息网官网查询,湛江网站建设策划介绍 我们可以想象这么一个场景,我们java应用想要采集到电表a的每小时的用电信息,我们怎么拿到电表的数据?一般我们会想 直接 java 后台发送请求给电表,然后让电表返回数据就可以了,事实上,我们java应用发…

介绍

我们可以想象这么一个场景,我们java应用想要采集到电表a的每小时的用电信息,我们怎么拿到电表的数据?一般我们会想 直接 java 后台发送请求给电表,然后让电表返回数据就可以了,事实上,我们java应用发送请求请求电表的数据信息并不是发到电表上,而是发送到 服务端 (broker)上,请求服务器 给我们电表的信息,而电表会把数据 按照mqtt协议 源源不断的发送到服务端,服务端可以把数据存储到物联网数据库上,也可以由我们java应用手动存储到物联网数据库上

而我们怎么知道电表发送到服务端的哪里,java应用又怎么请求到该电表发送的位置?

这就 引出了 一个概念,主题 (topic) ,这个topic在mqtt中不需要手动的创建,只要又客户端订阅或者发布消息,主题就会被自动创建出来

而我们服务端用的最多的就是 集成好的emqx服务器,本文我们也用的是集成好的emqx的服务端

,我们先是 一个电表 订阅好一个固定的主题,然后 源源不断的往服务端发消息,然后我们java应用订阅这个主题,这样 java应用就能持续的拿到电表的数据了

具体什么是主题,主题怎么设置的 ,mqtt协议的具体协议内容,直接登录emqx官网查看即可

MQTT 最全教程:从入门到精通 | EMQ

而emqx服务器是怎么在linux系统上搭建的呢,具体直接看文档即可,输入文档对应的yum命令就可以直接 在linux服务器上安装了

在 CentOS/RHEL 上安装 EMQX | EMQX文档

文本主要书写代码的实现

代码实现

我们的yml文件如下

 我们后续 java应用订阅消息 都要到服务端 emqx 的1883端口

实体类如下

 

这里解释一下 clientid 是不固定的,随机的每一个发布/订阅消息的客户端都有一个唯一的clientid

而username 和password 是 客户端连接到 服务端的认证账户,多个客户端可以使用一个 账号密码

客户端代码实现

@Slf4j
@Component
@RequiredArgsConstructor
public class EMQXClient {
private  final MqttDefaultProperties mqttDefaultProperties;
private  final IMessageCallbackImpl mqttCallback;private IMqttClient mqttClient;/*** 初始化客户端对象*/
public  boolean initMqttClient(String clientId,String serverUrl)  {MemoryPersistence memoryPersistence = new MemoryPersistence();try {if(Objects.isNull(clientId)){clientId= mqttDefaultProperties.getDefaultClientId();}if(Objects.isNull(serverUrl)){serverUrl= mqttDefaultProperties.getServerUrl();}mqttClient = new MqttClient(serverUrl, clientId, memoryPersistence);} catch (MqttException e) {log.info("mqtt创建异常:{}", e.getMessage());return  false;}return true;
}public  boolean initMqttClient()  {MemoryPersistence memoryPersistence = new MemoryPersistence();try {mqttClient = new MqttClient(mqttDefaultProperties.getServerUrl(),mqttDefaultProperties.getDefaultClientId(),  memoryPersistence);} catch (MqttException e) {log.info("mqtt创建异常:{}", e.getMessage());return  false;}return true;}/*** 获取连接* @return*/public   boolean connect()  {MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();//当客户端会话关闭的时候  对应的broker也关闭mqttConnectOptions.setCleanSession(true);//自动重连mqttConnectOptions.setAutomaticReconnect(true);mqttConnectOptions.setUserName(mqttDefaultProperties.getDefaultUserName());mqttConnectOptions.setPassword(mqttDefaultProperties.getDefaultPassword().toCharArray());mqttClient.setCallback(mqttCallback);try {mqttClient.connect(mqttConnectOptions);} catch (MqttException e) {log.info("客户端连接异常:{}",e.getMessage());return  false;}return true;}public   boolean connect(String username,String password)  {if(Objects.isNull(username)){username=mqttDefaultProperties.getDefaultUserName();}if(Objects.isNull(password)){password= mqttDefaultProperties.getDefaultPassword();}MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();//当客户端会话关闭的时候  对应的broker也关闭mqttConnectOptions.setCleanSession(true);//自动重连mqttConnectOptions.setAutomaticReconnect(true);mqttConnectOptions.setUserName(username);mqttConnectOptions.setPassword(password.toCharArray());mqttClient.setCallback(mqttCallback);try {mqttClient.connect(mqttConnectOptions);} catch (MqttException e) {log.info("客户端连接异常:{}",e.getMessage());return  false;}return true;
}/*** 断开连接* @return*/public  boolean disConnect(){try {mqttClient.disconnect();} catch (MqttException e) {log.info("客户端断开连接异常:{}",e.getMessage());return  false;}
return true;
}/**** @param topic 主题* @param msg 消息内容* @param qosEnum* @param retain  新的订阅者来了是否能拿到之前的 最新的一次消息* @return*/public  boolean publish(String topic, String msg, QosEnum qosEnum,boolean retain){int uniqueInt = (int) (System.nanoTime() & 0xFFFFFFFFL);//取纳秒时间戳低32位MqttMessage mqttMessage = new MqttMessage();mqttMessage.setPayload(msg.getBytes());mqttMessage.setQos(qosEnum.getType());mqttMessage.setRetained(retain);mqttMessage.setId(uniqueInt);try {mqttClient.publish(topic,mqttMessage);} catch (MqttException e) {log.info("客户端发送消息失败:{}",e.getMessage());return  false;}return  true;}/**** @param topicFilters 要订阅的主题 例子 testtopic/#* @param qosEnum* @return*/public boolean subscribe(String topicFilters,QosEnum qosEnum){try {mqttClient.subscribe(topicFilters,qosEnum.getType());} catch (MqttException e) {log.info("订阅主题失败:{}",e.getMessage());return  false;}return true;}
public boolean unSubscribe(String topicFilter){try {mqttClient.unsubscribe( topicFilter);} catch (MqttException e) {log.info("取消订阅主题失败:{}",e.getMessage());return false;}return  true;
}}

我们着重关注的是

我们想连接 服务端 是不是得有 一个client ,那这个client就对应IMqttclient

,我们java应用客户端连接上服务端之后,是不是得订阅主题,订阅之后的逻辑在哪里,就在

IMessageCallbackImpl

这里面就是 书写的 客户端收到服务端发来的消息之后的处理情况

@Slf4j
@Component
public class IMessageCallbackImpl  implements MessageCallback {@Overridepublic void connectionLost(Throwable cause) {//丢失对服务端的连接后触发该方法回调,此处可以做一些特殊处理,比如重连 或者记录 日志之类的log.info("丢失了对broker的连接");}/*** 订阅到消息后的回调* 该方法由mqtt客户端同步调用,在此方法未正确返回之前,不会发送ack确认消息到broker* 一旦该方法向外抛出了异常客户端将异常关闭,当再次连接时;所有QoS1,QoS2且客户端未进行ack确认的消息都将由broker服务器再次发送到客户端* @param topic* @param message* @throws Exception*/@Overridepublic void messageArrived(String topic, MqttMessage message) throws Exception {log.info("订阅到了消息;topic={},messageid={},qos={},msg={}",topic,message.getId(),message.getQos(),new String(message.getPayload()));}/*** 消息发布完成且收到ack确认后的回调* QoS0:消息被服务端发出后触发一次* QoS1:当收到broker的PUBACK消息后触发* QoS2:当收到broer的PUBCOMP消息后触发* @param token*/@Overridepublic void deliveryComplete(IMqttDeliveryToken token) {int messageId = token.getMessageId();String[] topics = token.getTopics();log.info("消息发送完成,messageId={},topics={}",messageId,topics);}
}

 

我们用一个 bean 在初始化的时候就订阅一个主题,这样 只要有 客户端往主题上发消息,我们就能收到了

而我们这个时候 没有硬件,怎么办呢,很简单,直接下载一个mqttx 模拟硬件发送消息到主题,启动springboot,就能看到消息的发送与接收了

当然 这实现的紧紧是最简单的协议的发送接收,后面还有许多的高级功能等我们使用,具体的可以查阅官方文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/896969.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue Table 表格自适应窗口高度,表头固定

当表格内纵向内容过多时&#xff0c;可选择固定表头。 代码很简单&#xff0c;其实就是在table 里面定一个 height 属性即可。 <template><el-table:data"tableData"height"250"borderstyle"width: 100%"><el-table-columnprop…

【ATXServer2】Android无法正确显示手机屏幕

文章目录 现象原因分析与解决排查手机内部minicap 解决minicap问题查看移动端Android SDK版本查看minicap支持版本单次方案多次方案 最后问题-如何支持Android SDK 32 现象 原因分析与解决 由于atxserver2在与Android动终端的链接过程中使用了agent&#xff1a;atxserver2-and…

【设计模式】单例模式|饿汉模式|懒汉模式|指令重排序

目录 1.什么是单例模式&#xff1f; 2.如何保证单例&#xff1f; 3.两种写法 &#xff08;1&#xff09;饿汉模式&#xff08;早创建&#xff09; &#xff08;2&#xff09;懒汉模式&#xff08;缓执行&#xff0c;可能不执行&#xff09; 4.应用场景 &#x1f525;5.多…

RocketMQ顺序消费机制

RocketMQ的顺序消费机制通过生产端和消费端的协同设计实现&#xff0c;其核心在于局部顺序性&#xff0c;即保证同一队列&#xff08;MessageQueue&#xff09;内的消息严格按发送顺序消费。以下是详细机制解析及关键源码实现&#xff1a; 一、顺序消费的核心机制 1. 生产端路…

【JavaEE】-- 多线程(初阶)4

文章目录 8.多线程案例8.1 单例模式8.1.1 饿汉模式8.1.2 懒汉模式 8.2 阻塞队列8.2.1 什么是阻塞队列8.2.2 生产者消费者模型8.2.3 标准库中的阻塞队列8.2.4 阻塞队列的应用场景8.2.4.1 消息队列 8.2.5 异步操作8.2.5 自定义实现阻塞队列8.2.6 阻塞队列--生产者消费者模型 8.3 …

【C++设计模式】第四篇:建造者模式(Builder)

注意&#xff1a;复现代码时&#xff0c;确保 VS2022 使用 C17/20 标准以支持现代特性。 分步骤构造复杂对象&#xff0c;实现灵活装配 1. 模式定义与用途 核心目标&#xff1a;将复杂对象的构建过程分离&#xff0c;使得同样的构建步骤可以创建不同的表示形式。 常见场景&am…

EP 架构:未来主流方向还是特定场景最优解?

DeepSeek MoE架构采用跨节点专家并行&#xff08;EP&#xff09;架构&#xff0c;在提升推理系统性能方面展现出巨大潜力。这一架构在发展进程中也面临诸多挑战&#xff0c;其未来究竟是会成为行业的主流方向&#xff0c;还是仅适用于特定场景&#xff0c;成为特定领域的最优解…

[密码学实战]Java实现国密(SM2)密钥协商详解:原理、代码与实践

一、代码运行结果 二、国密算法与密钥协商背景 2.1 什么是国密算法&#xff1f; 国密算法是由中国国家密码管理局制定的商用密码标准&#xff0c;包括&#xff1a; SM2&#xff1a;椭圆曲线公钥密码算法&#xff08;非对称加密/签名/密钥协商&#xff09;SM3&#xff1a;密码…

动漫短剧开发公司,短剧小程序搭建快速上线

在当今快节奏的生活里&#xff0c;人们的娱乐方式愈发多元&#xff0c;而动漫短剧作为新兴娱乐形式&#xff0c;正以独特魅力迅速崛起&#xff0c;成为娱乐市场的耀眼新星。近年来&#xff0c;动漫短剧市场呈爆发式增长&#xff0c;吸引众多创作者与观众目光。 从市场规模来看…

Python测试框架Pytest的参数化

上篇博文介绍过&#xff0c;Pytest是目前比较成熟功能齐全的测试框架&#xff0c;使用率肯定也不断攀升。 在实际工作中&#xff0c;许多测试用例都是类似的重复&#xff0c;一个个写最后代码会显得很冗余。这里&#xff0c;我们来了解一下pytest.mark.parametrize装饰器&…

开发博客系统

前言 准备工作 数据库表分为实体表和关系表 第一&#xff0c;建数据库表 然后导入前端页面 创建公共模块 就是统一返回值&#xff0c;异常那些东西 自己造一个自定义异常 普通类 mapper 获取全部博客 我们只需要返回id&#xff0c;title&#xff0c;content&#xff0c;us…

20250304学习记录

第一部分&#xff0c;先来了解一下各种论文期刊吧&#xff0c;毕竟也是这把岁数了&#xff0c;还什么都不懂呢 国际期刊&#xff1a; EI收集的主要有两种&#xff0c; JA&#xff1a;EI源刊 CA&#xff1a;EI会议 CPCI也叫 ISTP 常说的SCI分区是指&#xff0c;JCR的一区、…

2024 年 MySQL 8.0.40 安装配置、Workbench汉化教程最简易(保姆级)

首先到官网上下载安装包&#xff1a;http://www.mysql.com 点击下载&#xff0c;拉到最下面&#xff0c;点击社区版下载 windows用户点击下面适用于windows的安装程序 点击下载&#xff0c;网络条件好可以点第一个&#xff0c;怕下着下着断了点第二个离线下载 双击下载好的安装…

汽车智能钥匙中PKE低频天线的作用

PKE&#xff08;Passive Keyless Entry&#xff09;即被动式无钥匙进入系统&#xff0c;汽车智能钥匙中PKE低频天线在现代汽车的智能功能和安全保障方面发挥着关键作用&#xff0c;以下是其具体作用&#xff1a; 信号交互与身份认证 低频信号接收&#xff1a;当车主靠近车辆时…

uiautomatorviewer定位元素报Unexpected ... UI hierarchy

发现问题 借鉴博客 Unexpected error while obtaining UI hierarchy android app UI自动化-元素定位辅助工具 Unexpected error while obtaining UI hierarchy&#xff1a;使用uiautomatorviewer定位元素报错 最近在做安卓自动化,安卓自动化主要工作之一就是获取UI树 app端获…

Halcon 车牌识别-超精细教程

车牌示例 流程: 读取图片转灰度图阈值分割,找车牌内容将车牌位置设置变换区域形状找到中心点和弧度利用仿射变换,斜切车牌旋转转正,把车牌抠出来利用形态学操作拼接车牌号数字训练ocr开始识别中文车牌 本文章用到的算子(解析) Halcon 算子-承接车牌识别-CSDN博客 rgb1_to_gray…

详细分析KeepAlive的基本知识 并缓存路由(附Demo)

目录 前言1. 基本知识2. Demo2.1 基本2.2 拓展2.3 终极 3. 实战 前言 &#x1f91f; 找工作&#xff0c;来万码优才&#xff1a;&#x1f449; #小程序://万码优才/r6rqmzDaXpYkJZF 基本知识推荐阅读&#xff1a;KeepAlive知识点 从实战中学习&#xff0c;源自实战中vue路由的…

记一次误禁用USB导致键盘鼠标失灵的修复过程

背景说明 在电脑上插入了一个USB hub&#xff0c;然后弹窗提示&#xff1a;“集线器端口上出现电涌”&#xff0c;点开让选择“重置”或者“关闭”&#xff0c;不小心点了关闭&#xff0c;结果这个usb口就被关了&#xff0c;再插任何东西都没反应&#xff0c;找了很多办法都恢…

小米手机如何录制屏幕?手机、电脑屏幕录制方法分享

大家最近有没有遇到想记录手机屏幕操作的情况&#xff1f; 比如精彩的游戏瞬间、有趣的视频教程&#xff0c;或者需要录制屏幕来制作演示材料。小米手机在这方面可是个好帮手&#xff0c;今天就来给你好好唠唠&#xff0c;小米手机如何录制屏幕&#xff0c;以及后续如何处理这…

chrome Vue.js devtools 提示不支持该扩展组件,移除

可能是版本不兼容&#xff0c;可以重新安装&#xff0c;推荐网址极简插件官网_Chrome插件下载_Chrome浏览器应用商店 直接搜索vue&#xff0c;下载旧版&#xff0c;vue2、vue3都支持&#xff0c;上面那个最新版本试了下&#xff0c;vue2的肯定是不能用