mosquitto的TLS功能: (使用paho.mqtt.golang和JAVA版实现客户端)

EMQX 服务器建立SSL/TLS安全连接、单向、双向 ssl/tls加密 阅读详情

1、SSL/TLS简介

  SSL(SecureSocket Layer)安全套接层,是网景公司提出的用于保证Server与client之间安全通信的一种协议,该协议位于TCP/IP协议与各应用层协议之间,即SSL独立于各应用层协议,因此各应用层协议可以透明地调用SSL来保证自身传输的安全性。目前,SSL被大量应用于http的安全通信中,MQTT协议与http协议同样属于应用层协议,因此也可以像http协议一样使用ssl为自己的通信提供安全保证。

  SSL与TLS(Transport LayerSecurity Protocol)之间的关系:TLS(TransportLayer Security,传输层安全协议)是IETF(InternetEngineering Task Force,Internet工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本。在TLS与SSL3.0之间存在着显著的差别,主要是它们所支持的加密算法不同,所以TLS与SSL3.0不能互操作。

2、使用Openssl创建tls证书

  SSL在身份认证过程中需要有一个双方都信任的CA签发的证书,CA签发证书是需要收费的,但是在测试过程中,可以自己产生一个CA,然后用自己产生的CA签发证书,下面的mosquitto的ssl功能的测试过程就是采用这一方式,其过程如下:

步骤一:产生自己的CA

openssl req -new -x509 -days 36500 -extensions v3_ca -keyout ca.key -out ca.crt
openssl req -new -x509 -days 36500 -extensions v3_ca -keyout ca.key -out ca.pem

步骤二:产生服务端证书

openssl genrsa -des3 -out server.key 2048
openssl req -out server.csr -key server.key -new
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 36500

步骤三:产生客户端证书

openssl genrsa -out client-key.pem 2048
openssl req -out client.csr -key client-key.pem -new
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client-crt.pem -days 36500

经过上面8条命令后,即可生成所需的所有证书文件,其中:

客户端使用:ca.pem、client-crt.pem、client-key.pem

服务端使用:ca.crt、server.crt、server.key

3、mosquitto.conf配置如下:

4、golang客户端测试代码

复制代码
  1 package cmd
  2 
  3 import (
  4     "crypto/tls"
  5     "crypto/x509"
  6     fmt "fmt"
  7     "io/ioutil"
  8     "os"
  9     "time"
 10 
 11     "github.com/apex/log"
 12     MQTT "github.com/eclipse/paho.mqtt.golang"
 13 )
 14 
 15 var ctx log.Interface
 16 
 17 const QoS = 0x02
 18 
 19 func init() {
 20     fmt.Printf("init mqtt test\n")
 21 
 22 }
 23 
 24 func RunMqttClient() {
 25     fmt.Printf("Run mqtt test\n")
 26     var logLevel = log.InfoLevel
 27     ctx = &log.Logger{
 28         Level:   logLevel,
 29         Handler: NewLogHanler(os.Stdout),
 30     }
 31 
 32     mqttClient := NewClient(
 33         ctx,
 34         "ttnhdl",
 35         "",
 36         "",
 37         fmt.Sprintf("ssl://%s", "192.168.195.201:8883"),
 38     )
 39 
 40     var err = mqttClient.Connect()
 41     if err != nil {
 42         ctx.WithError(err).Fatal("Could not connect to MQTT")
 43         fmt.Printf("Could not connect to MQTT\n")
 44     } else {
 45         fmt.Printf("Success connect to MQTT\n")
 46     }
 47 
 48     mqttClient.PublishUplink("test", "hello mqtt!")
 49     mqttClient.SubscribeUplink("test")
 50 
 51     for true {
 52 
 53     }
 54 }
 55 
 56 // Client connects to the MQTT server and can publish/subscribe on uplink, downlink and activations from devices
 57 type Client interface {
 58     Connect() error
 59     Disconnect()
 60 
 61     IsConnected() bool
 62 
 63     // Uplink pub/sub
 64     PublishUplink(topic string, msg string) Token
 65     SubscribeUplink(topic string) Token
 66 }
 67 
 68 type Token interface {
 69     Wait() bool
 70     WaitTimeout(time.Duration) bool
 71     Error() error
 72 }
 73 
 74 type simpleToken struct {
 75     err error
 76 }
 77 
 78 // Wait always returns true
 79 func (t *simpleToken) Wait() bool {
 80     return true
 81 }
 82 
 83 // WaitTimeout always returns true
 84 func (t *simpleToken) WaitTimeout(_ time.Duration) bool {
 85     return true
 86 }
 87 
 88 // Error contains the error if present
 89 func (t *simpleToken) Error() error {
 90     return t.err
 91 }
 92 
 93 type defaultClient struct {
 94     mqtt MQTT.Client
 95     ctx  log.Interface
 96 }
 97 
 98 func NewClient(ctx log.Interface, id, username, password string, brokers ...string) Client {
 99     tlsconfig := NewTLSConfig()
100 
101     mqttOpts := MQTT.NewClientOptions()
102 
103     for _, broker := range brokers {
104         mqttOpts.AddBroker(broker)
105     }
106 
107     mqttOpts.SetClientID("ypf_dewqfvcdeqfcdqwcdq")
108     mqttOpts.SetUsername(username)
109     mqttOpts.SetPassword(password)
110 
111     // TODO: Some tuning of these values probably won't hurt:
112     mqttOpts.SetKeepAlive(30 * time.Second)
113     mqttOpts.SetPingTimeout(10 * time.Second)
114 
115     // Usually this setting should not be used together with random ClientIDs, but
116     // we configured The Things Network's MQTT servers to handle this correctly.
117     mqttOpts.SetCleanSession(false)
118 
119     mqttOpts.SetDefaultPublishHandler(func(client MQTT.Client, msg MQTT.Message) {
120         ctx.WithField("message", msg).Warn("Received unhandled message")
121     })
122 
123     mqttOpts.SetConnectionLostHandler(func(client MQTT.Client, err error) {
124         ctx.WithError(err).Warn("Disconnected, reconnecting...")
125     })
126 
127     mqttOpts.SetOnConnectHandler(func(client MQTT.Client) {
128         ctx.Debug("Connected")
129     })
130 
131     mqttOpts.SetTLSConfig(tlsconfig)
132 
133     return &defaultClient{
134         mqtt: MQTT.NewClient(mqttOpts),
135         ctx:  ctx,
136     }
137 }
138 
139 var (
140     // ConnectRetries says how many times the client should retry a failed connection
141     ConnectRetries = 10
142     // ConnectRetryDelay says how long the client should wait between retries
143     ConnectRetryDelay = time.Second
144 )
145 
146 func (c *defaultClient) Connect() error {
147     if c.mqtt.IsConnected() {
148         return nil
149     }
150     var err error
151     for retries := 0; retries < ConnectRetries; retries++ {
152         token := c.mqtt.Connect()
153         token.Wait()
154         err = token.Error()
155         if err == nil {
156             break
157         }
158         <-time.After(ConnectRetryDelay)
159     }
160     if err != nil {
161         return fmt.Errorf("Could not connect: %s", err)
162     }
163     return nil
164 }
165 
166 func (c *defaultClient) Disconnect() {
167     if !c.mqtt.IsConnected() {
168         return
169     }
170     c.mqtt.Disconnect(25)
171 }
172 
173 func (c *defaultClient) IsConnected() bool {
174     return c.mqtt.IsConnected()
175 }
176 
177 func (c *defaultClient) PublishUplink(topic string, msg string) Token {
178     return c.mqtt.Publish(topic, QoS, false, msg)
179 }
180 
181 func (c *defaultClient) SubscribeUplink(topic string) Token {
182     return c.mqtt.Subscribe(topic, QoS, func(mqtt MQTT.Client, msg MQTT.Message) {
183         // Determine the actual topic
184         fmt.Printf("Success SubscribeUplink with msg:%s\n", msg.Payload())
185     })
186 }
187 
188 func NewTLSConfig() *tls.Config {
189     // Import trusted certificates from CAfile.pem.
190     // Alternatively, manually add CA certificates to
191     // default openssl CA bundle.
192     certpool := x509.NewCertPool()
193     pemCerts, err := ioutil.ReadFile("samplecerts/ca.pem")
194     if err == nil {
195         certpool.AppendCertsFromPEM(pemCerts)
196     }
197     fmt.Println("0. resd pemCerts Success")
198 
199     // Import client certificate/key pair
200     cert, err := tls.LoadX509KeyPair("samplecerts/client-crt.pem", "samplecerts/client-key.pem")
201     if err != nil {
202         panic(err)
203     }
204     fmt.Println("1. resd cert Success")
205 
206     // Just to print out the client certificate..
207     cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
208     if err != nil {
209         panic(err)
210     }
211     fmt.Println("2. resd cert.Leaf Success")
212 
213     // Create tls.Config with desired tls properties
214     return &tls.Config{
215         // RootCAs = certs used to verify server cert.
216         RootCAs: certpool,
217         // ClientAuth = whether to request cert from server.
218         // Since the server is set up for SSL, this happens
219         // anyways.
220         ClientAuth: tls.NoClientCert,
221         // ClientCAs = certs used to validate client cert.
222         ClientCAs: nil,
223         // InsecureSkipVerify = verify that cert contents
224         // match server. IP matches what is in cert etc.
225         InsecureSkipVerify: true,
226         // Certificates = list of certs client sends to server.
227         Certificates: []tls.Certificate{cert},
228     }
229 }
复制代码

 5、测试效果

服务端启动:

客户端运行:

 

6、JAVA版客户端实现

依赖:org.eclipse.paho.client.mqttv3、bcprov-jdk16-1.45.jar

MqttServiceClient代码:

复制代码
  1 package com.ypf.main;
  2 
  3 import java.util.Properties;
  4 
  5 import org.eclipse.paho.client.mqttv3.MqttCallback;
  6 import org.eclipse.paho.client.mqttv3.MqttClient;
  7 import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
  8 import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
  9 import org.eclipse.paho.client.mqttv3.MqttException;
 10 import org.eclipse.paho.client.mqttv3.MqttMessage;
 11 import org.eclipse.paho.client.mqttv3.MqttSecurityException;
 12 import org.eclipse.paho.client.mqttv3.MqttTopic;
 13 import org.eclipse.paho.client.mqttv3.internal.MemoryPersistence;
 14 
 15 import com.ypf.mqtt.SslUtil;
 16 
 17 /** 
 18  * 
 19  * @author LP by 2014-04-24
 20  *
 21  */
 22 public class MqttServiceClient implements MqttCallback {
 23 
 24     private static final String MQTT_HOST = "ssl://192.168.195.201:8884";
 25     private static final String MQTT_CLIENT = "Test_";
 26     public static String caFilePath = "D:/for-iot/LURA/src/mytest/samplecerts/ca.crt";
 27     public static String clientCrtFilePath = "D:/for-iot/LURA/src/mytest/samplecerts/client.crt";
 28     public static String clientKeyFilePath = "D:/for-iot/LURA/src/mytest/samplecerts/client.key";
 29     
 30     public static MqttServiceClient mqttServiceClient = null;
 31     
 32     private MqttClient client = null;
 33     private MqttConnectOptions options = null;
 34     
 35     /**
 36      * 单例模式构造类
 37      */
 38     public static MqttServiceClient getInstance() {
 39         if (mqttServiceClient == null) {
 40             mqttServiceClient = new MqttServiceClient();
 41         }
 42         return mqttServiceClient;
 43     }
 44 
 45     private MqttServiceClient() {
 46         System.out.println("init MQTTClientService");
 47         init();
 48     }
 49     // The major API implementation follows :-
 50 
 51     /**
 52      * 初始化
 53      */
 54     private void init() {
 55         try {
 56         
 57             // host为主机名,test为clientid即连接MQTT的客户端ID,一般以客户端唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存
 58             client = new MqttClient(MQTT_HOST, MQTT_CLIENT, new MemoryPersistence());
 59             // MQTT的连接设置
 60             options = new MqttConnectOptions();
 61             // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接
 62             options.setCleanSession(true);
 63             // 设置连接的用户名
 64             options.setUserName("ypf");
 65             // 设置连接的密码
 66             options.setPassword("ruijie".toCharArray());
 67             // 设置超时时间 单位为秒
 68             options.setConnectionTimeout(50);
 69             // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
 70             options.setKeepAliveInterval(30);
 71             // TLS连接配置
 72             options.setSocketFactory(
 73                     SslUtil.getSocketFactory(caFilePath, clientCrtFilePath, clientKeyFilePath, "cs123456"));
 74 
 75             // 设置回调
 76             client.setCallback(this);
 77             
 78         } catch (Exception e) {
 79             e.printStackTrace();
 80         }
 81     }
 82     /**
 83      * 连接到MQTT
 84      */
 85     void connect() {
 86         System.out.println("Start connect----------");
 87         try {
 88             client.connect(options);
 89             //订阅主题的方法,2为消息的质量
 90             client.subscribe("+/#", 2);
 91             //发送消息
 92             publish("test", "撒打发水电费水电费");
 93         } catch (Exception e) {
 94             e.printStackTrace();
 95         }
 96     }
 97     
 98     /**
 99      * 断开连接到MQTT
100      */
101     public void disconnect() {
102         System.out.println("Start disconnect----------");
103         try {
104             client.disconnect();
105         } catch (MqttSecurityException e) {
106             e.printStackTrace();
107         } catch (MqttException e) {
108             e.printStackTrace();
109         }
110     }
111 
112     /** 
113      * 发布消息
114      * @param topic 主题
115      * @param msg 消息
116      */
117     public void publish(String topic, String msg) {
118         System.out.println("Start publish----------");
119         try {
120             MqttTopic mqttTopic = client.getTopic(topic);
121             //2为消息的质量
122             MqttDeliveryToken messageToken = mqttTopic.publish(msg.getBytes(), 2, true);
123             System.out.println("publish success==>"+messageToken.getMessage());
124 //            client.publish(topic, 2, msg);
125         } catch (Exception e) {
126             e.printStackTrace();
127         }
128     }
129     
130     
131 // -------------------------------------------------回调方法------------------------------------------------------------//
132     
133     /** 
134      * 连接断开触发此方法
135      */
136     @Override
137     public void connectionLost(Throwable cause) {
138         System.out.println("Connection Lost---------->" + cause.getMessage());
139     }
140 
141     /** 
142      * 消息达到触发此方法
143      */
144     @Override
145     public void messageArrived(MqttTopic topic, MqttMessage message)
146             throws Exception {
147         System.out.println(topic + ":" + message.toString());
148     }
149 
150     /**
151      * 消息发送成功触发此方法
152      */
153     @Override
154     public void deliveryComplete(MqttDeliveryToken token)  {
155         try {
156             System.out.println("deliveryComplete---------" + token.getMessage());
157         } catch (MqttException e) {
158             e.printStackTrace();
159         }
160     }
161 
162     
163     public static void main(String[] args)throws Exception {
164         
165         //MqttServiceClient.getInstance().disconnect();
166         MqttServiceClient.getInstance().connect();
167         
168         new Thread() {
169             public void run() {
170                 int count = 0;
171                 while(true && count < 3) {
172                     try {
173                         Thread.sleep(1000*3);
174                     } catch (InterruptedException e) {
175                         e.printStackTrace();
176                     }
177                     MqttServiceClient.getInstance().publish("test1/ypf", "hello world ! count=" + count);
178                     count ++;
179                 }
180             };
181         }.start();
182     }
183     
184 }
复制代码

SslUtil代码:
复制代码
 1 package com.ypf.mqtt;
 2 
 3 import java.io.ByteArrayInputStream;
 4 import java.io.InputStreamReader;
 5 import java.nio.file.Files;
 6 import java.nio.file.Paths;
 7 import java.security.KeyPair;
 8 import java.security.KeyStore;
 9 import java.security.Security;
10 import java.security.cert.X509Certificate;
11 
12 import javax.net.ssl.KeyManagerFactory;
13 import javax.net.ssl.SSLContext;
14 import javax.net.ssl.SSLSocketFactory;
15 import javax.net.ssl.TrustManagerFactory;
16 
17 import org.bouncycastle.jce.provider.BouncyCastleProvider;
18 import org.bouncycastle.openssl.*;
19 
20 public class SslUtil {
21     public static SSLSocketFactory getSocketFactory(final String caCrtFile, final String crtFile, final String keyFile,
22             final String password) throws Exception {
23         Security.addProvider(new BouncyCastleProvider());
24 
25         // load CA certificate
26         PEMReader reader = new PEMReader(
27                 new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(caCrtFile)))));
28         X509Certificate caCert = (X509Certificate) reader.readObject();
29         reader.close();
30 
31         // load client certificate
32         reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(crtFile)))));
33         X509Certificate cert = (X509Certificate) reader.readObject();
34         reader.close();
35 
36         // load client private key
37         reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(keyFile)))),
38                 new PasswordFinder() {
39                     @Override
40                     public char[] getPassword() {
41                         return password.toCharArray();
42                     }
43                 });
44         KeyPair key = (KeyPair) reader.readObject();
45         reader.close();
46 
47         // CA certificate is used to authenticate server
48         KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
49         caKs.load(null, null);
50         caKs.setCertificateEntry("ca-certificate", caCert);
51         TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
52         tmf.init(caKs);
53 
54         // client key and certificates are sent to server so it can authenticate
55         // us
56         KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
57         ks.load(null, null);
58         ks.setCertificateEntry("certificate", cert);
59         ks.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(),
60                 new java.security.cert.Certificate[] { cert });
61         KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
62         kmf.init(ks, password.toCharArray());
63 
64         // finally, create SSL socket factory
65         SSLContext context = SSLContext.getInstance("TLSv1");
66         context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
67 
68         return context.getSocketFactory();
69     }
70 }
mosquito服务器搭建配置通信 ssl/tls 安全 mosquito服务器实现 ssl/tls 安全配置通信 阅读详情

相关推荐

MQTT协议应用TLS

前言 做了很久的实验,一直没能成功,最后还是down的大佬的源码,侵删。 正文 简介 MQTT协议是物联网应用中重要的应用层协议,上一次实验开展了MQTT协议的分析,对MQTT协议的长连接机制、发布/订阅工作模式交互机制进行了分析。但如果MQTT协议不进行安全实现,黑客可以恶意发布信息给服务器,特别是在工业、交通等物联网应用场合后果不堪设想。本实验旨构建MQTT协议安全通信。 要求 (1)掌握MQ...

qq_41381461的博客 8234

mosquitto 测试MQTT TLS单向认证和双向认证

文章目录mosquitto.conf 配置MQTT Client 调测参考资料 mosquitto.conf 配置 mosquitto.conf man page https://mosquitto.org/man/mosquitto-conf-5.html 配置TLS单向认证 修改mosquitto.conf文件,可直接在文件末尾追加 listener 8883 protocol mqtt cafile C:\mosquitto\ca\ca.crt certfile C:\mosquitto\ca\ser

mayue_web的博客 1万+

国产MQTT协议栈替换Mosquitto/EMQX:选型迁移与许可证合规实践

MQTT作为物联网场景下的主流消息协议,其Broker与客户端协议栈的选型直接影响系统的可维护性与商用合规性。Mosquitto和EMQX虽分别以轻量与分布式能力著称,但面对国产化申报、开源许可证审计及长期交付需求时,仅靠“开源”二字并不能化解全部风险。EPL、Apache 2.0等许可证在修改分发、专利授权与商标使用上的差异,决定了不同业务场景下替代策略的复杂性。以NanoMQ、Mica-MQTT、Gmqtt为代表的国产MQTT组件,凭借宽松的Apache 2.0许可和更贴合边缘侧、内嵌式、Java/Go

weixin_29164843的博客 128

搭建mosquitto ssl/tls 认证保姆级教学

生成服务器ca-cert.pem,client-cert.pem和client-key.pem来支持SSL连接。我设法通过以下步骤将Java客户端连接到Cloud SQL。执行openssl脚本生成ca.crt ca.key client.crt client.key server.key server.crt。cmd命令工具,输入一下命令:会生成 truststore、keystore 2个文件。保姆级别教学

liu942947766的博客 2742

Mosquitto替换指南:国产MQTT协议栈选型与迁移实践

MQTT作为物联网设备接入的事实标准,其协议栈选型直接影响系统稳定性和合规审计。开源许可证条款差异是技术选型中的关键风险点:EPL-2.0属于弱Copyleft,修改文件需公开源码,而Apache 2.0宽松无传染性,且包含专利授权保护,更适合嵌入式交付和商业闭源。在实际替换场景中,需要区分broker、client SDK和协议语义三个层次,评估报文解析、QoS状态机、通配符匹配等细节。从Mosquitto或EMQX迁移时,配置映射、ACL粒度、会话重建和灰度切流都是必经环节。本文结合工程实践,盘点Nan

weixin_34008784的博客 738

MQTT协议栈国产替代:从Mosquitto到BifroMQ的合规与迁移实战

消息队列遥测传输(MQTT)凭借轻量级、低带宽的特点,成为物联网设备接入的主流协议。Broker作为消息中枢,其开源许可证类型直接决定了商用边界与合规风险。EPL-2.0与Apache 2.0在传染性、专利授权及分发义务上差异显著,Mosquitto的双许可机制与EMQX企业版功能隔离常让选型团队陷入误区。理解许可证条款、评估Broker的集群能力与可观测性,是保障大规模设备连接稳定性的关键前提。无论是新能源充电桩、工业网关还是边缘计算场景,迁移MQTT协议栈都需要从连接层、会话语义到监控体系逐项对齐。本文

weixin_33788244的博客 322

mosquitto的TLS功能测试,客户端使用paho.mqtt.golang(附JAVA版客户端实现)

1、SSL/TLS简介   SSL(SecureSocket Layer)安全套接层,是网景公司提出的用于保证Server与client之间安全通信的一种协议,该协议位于TCP/IP协议与各应用层协议之间,即SSL独立于各应用层协议,因此各应用层协议可以透明地调用SSL来保证自身传输的安全性。目前,SSL被大量应用于http的安全通信中,MQTT协议与http协议同样属于应用层协议,因...

weixin_30263073的博客 639

MQTT开源许可证合规指南:Mosquitto与EMQX的商用风险及国产替代迁移

在物联网和嵌入式系统开发中,MQTT作为轻量级消息传输协议被广泛采用,而围绕其协议栈与Broker的开源许可证问题常被忽视。理解EPL、Apache 2.0等许可证的分发义务与衍生作品边界,是规避商用法律风险的基础。Mosquitto采用EPL/EDL双许可,修改后对外分发或静态链接进固件可能触发源码开放要求;EMQX开源版基于Apache 2.0,宽松但仍需保留版权声明并注意商标限制。随着国产MQTT组件兴起,团队更需理性评估替代方案的生态完整性与许可证合规性。从功能依赖扫描、最小环境验证到客户端平滑切换

cuixie2370的博客 295

采用MQTT协议实现android消息推送(2)MQTT服务端与客户端软件对比、android客户端示列表...

1.服务端软件对比   https://github.com/mqtt/mqtt.github.io/wiki/servers 名称(点名进官网) 特性 简介 收费 支持的客户端语言 IBM MQ 完整的MQTT v3.1 IBM MQ JMS 企业级 IBM MQ(之前称作 WebSphere MQ)是一个安全...

banyinlve3147的博客 1514

国产MQTT协议栈替代Mosquitto/EMQX:选型、迁移与许可证风险全解析

MQTT作为物联网事实标准协议,广泛用于设备接入与消息分发。开源Broker如Mosquitto和EMQX虽成熟,但在商业交付中面临许可证合规、供应链可控性等风险。理解EPL、Apache 2.0等开源许可证的传染性、专利条款与商用边界,是选型前的基础。从协议兼容性、迁移成本、配置映射等工程视角出发,对比国产MQTT协议栈与平台方案,梳理从设备端到服务端的替换路径,并给出依赖树审计与SBOM落地建议,帮助团队在合规前提下实现平滑迁移。

weixin_34268753的博客 318

MQTT工具链全解析:从协议原理到生产环境部署实战

MQTT作为一种轻量级的发布/订阅消息传输协议,其核心价值在于为物联网和实时数据交互场景提供了高效、低功耗的通信基础。协议基于TCP/IP构建,通过主题过滤机制实现消息路由,其服务质量等级保证了不同场景下的消息可靠性。在工程实践中,构建健壮的MQTT系统不仅需要理解协议本身,更依赖于对服务端与客户端工具链的深入掌握和正确运用。服务端作为中枢,其选型需综合考量连接管理、消息路由、安全认证和监控运维等核心职责,而客户端工具则覆盖了从业务集成到调试排错的全流程。掌握包括Mosquitto、EMQX等在内的服务端部

weixin_34318272的博客 383

mosquitto 和 paho 选型,用 TaoToken 接入的 Codex 能对比

mosquitto 和 paho 不是同一层工具:前者是 MQTT broker,负责消息路由;后者是客户端 SDK,嵌入设备固件。本文以嵌入式调试为背景,使用接入 TaoToken 的 Codex 做选型对比,先改 ~/.codex/config.toml,在 model_providers 中新增 taotoken 并指向 base_url,再通过命令验证链路。同时结合局域网/公网环境、日志量、AT+MQTTCONN 流程给出落地组合,并梳理连接报错排查顺序。完整配置入口见 https://taotok

weixin_42610671的博客 9

第3章 zynq MII转GMII的配置和EMIO UART0的配置

本文介绍了在Vivado工程中实现MII转GMII接口适配的过程,同时配置EMIO UART0接口。主要内容包括:修改PS IP核添加UART0接口,使用concat IP核进行信号整合,调整GMII信号引脚连接,添加约束文件定义引脚映射,并最终生成bit流文件。通过详细的操作截图和TCL约束代码,展示了从硬件配置到生成可编程文件的完整流程,为Zynq平台开发提供了实用参考。

qq_36517072的博客 903

MQTT网关实战:从协议转换到生产部署的完整指南

在物联网系统中,协议转换是实现异构设备互联的关键技术。其核心原理是通过中间件将不同通信协议的数据统一转换为标准化的消息格式,从而实现设备与平台间的无缝通信。这项技术的价值在于解决了智能家居、工业物联网等领域中设备协议碎片化的问题,大幅降低了系统集成复杂度。MQTT作为一种轻量级的发布/订阅消息传输协议,因其低带宽消耗和可靠性,成为物联网数据上云的理想选择。在实际应用场景中,基于Python等语言实现的MQTT网关能够高效完成Modbus、Zigbee等协议到MQTT的转换,并通过分层架构设计确保系统的可扩展

weixin_34274029的博客 438

解决Surface更新后Bitlocker无限循环的问题

在Surface系统更新以后,出现要求输入Bitlocker恢复密钥的问题。已经输入正确密钥以后,依然无法正常进入Windows操作系统,一旦重启依然循环Bitlocker要求输入密钥的界面。 一旦到登录界面,点击“登录”之后又跳转回登录界面.,但就是无法进入桌面。 解决方案: 拒绝暴力重装!这个问题是Bitlock把盘给锁了,所以要解锁 重启之后,直接点击右下角“跳过这个驱动器” 选择“疑难解答”,然后进入命令提示符 先查看判断现在是不是被锁了: 输入: manage-bde -status c

premierapp的博客 1万+

HUMAnN 3.0 (alpha)安装及使用

文章目录简介安装数据库下载运行参考 简介 安装 conda install humann humann_test (~1 minute) 数据库下载 humann_databases --download chocophlan full /path/to/databases --update-config yes humann_databases --download uniref uniref90_diamond /path/to/databases --update-config yes humann_

dys的博客 9505

国产MQTT协议栈替换Mosquitto/EMQX:许可证、功能对比与迁移实战

MQTT作为物联网场景下最主流的轻量级消息传输协议,承担着海量设备与云端平台之间的实时数据通信任务。在实际工程落地中,Mosquitto和EMQX等常见开源Broker虽然功能完善,但其开源许可证(如EPL、Apache 2.0)在商用闭源分发、二次修改和SaaS服务等场景下存在不容忽视的合规边界,而国内团队维护的MQTT协议栈在授权清晰度、国密算法适配以及私有化交付方面逐渐展现出独特的替代价值。理解许可证传染性、功能覆盖差异与性能特征,是评估替代可行性的基础;通过合理的迁移路线,包括认证鉴权、TLS配置、

weixin_34302798的博客 389

别再为Word转PDF表格变形发愁了!Aspose.Words for Java 19.5 保姆级避坑指南

本文详细介绍了使用Aspose.Words for Java 19.5解决Word转PDF时表格变形问题的完整方案。从格式转换原理到实战技巧,涵盖固定表格宽度、禁用自动调整、强制文本换行等核心方法,并提供高级场景应对策略和性能优化建议,帮助开发者高效处理复杂文档转换需求。

weixin_28702105的博客 266

MQTT协议为什么成为物联网协议

这些特性精准解决了物联网设备在资源受限、网络不稳定环境下的通信需求。MQTT协议之所以成为物联网领域的核心通信协议,主要得益于其。

wtbl007的博客 376

Python读取Matlab v7.3数据

文章目录Matlab保存数据Python读取 v7.3 Mat Matlab保存数据 在matlab设置中,常规->MAT文件,选择MATLAB版本7.3或更高版本保存数据。 注意保存数据的文件名为 corre.mat,保存的数据数组为data; 后面python的读取中会用到这两个参数 Python读取 v7.3 Mat 先安装hdf5storage库,再使用以下代码,就可以读取到mat中的数据,注意 import hdf5storage import numpy as np dataDi

weixin_43121914的博客 1081

全面讲解电子齿轮比与脉冲数计算

什么是编码器分辨率。

viixin的博客 1万+

国产MQTT协议栈替代指南:从Mosquitto/EMQX迁移的选型与实操

消息中间件是物联网设备接入与数据流转的核心枢纽,而MQTT协议凭借轻量级发布/订阅模型成为该领域事实标准。面对Mosquitto、EMQX等主流broker,团队常纠结于开源许可证合规性与商业订阅成本。EPL、Apache 2.0等协议虽允许商用,但依赖传染、商标授权、企业版锁定等隐性风险仍值得警惕。从工程实践角度看,国产化替代并非简单更换软件,而需从协议兼容性、二次开发自由度、供应链审计等维度综合选型。无论采用NanoMQ、Java系broker还是自研轻量级协议栈,迁移过程都需遵循兼容性盘点、配置映射、

weixin_34195142的博客 388

51智能小车(双轮)

前几天接了个小单子,是一个基于51单品机的作品,发现自己对小车的认识还是不太🆗。也算是完成了任了的;欢迎各位小伙伴来多多交流,大家一起进步。最后有需要单片机课程设计的小伙伴滴滴我哦(有偿)。企鹅:2397746994。

qq_56992543的博客 2346

MQTT协议栈国产替代实战:从Mosquitto/EMQX迁移到合规自研

MQTT作为物联网场景下最主流的消息传输协议,其broker选型直接关系到设备接入的稳定性与商业合规性。在开源与国产化的双重浪潮下,越来越多的团队开始审视基于Eclipse Mosquitto或EMQX构建的消息层是否存在许可证传染、商标风险与供应链隐患。开源许可证并非一纸空文,EPL与Apache 2.0在实际分发、修改、静态链接等场景下有着截然不同的义务边界;而真正的自主可控,也不等同于另起炉灶重写协议栈,而是通过构建依赖清单、维护NOTICE声明、隔离商标标识、沉淀灰度迁移路径等方式,将第三方代码的不

weixin_34405354的博客 349

webrtc进阶-- FlexFEC 实现原理与调试分析(m80 代码对齐版)

WebRTC 中 FlexFEC 技术解析与调试指南 摘要:本文深入分析 WebRTC 的 FlexFEC(灵活前向纠错)技术实现原理,重点探讨其在 m80 版本中的协商机制、接收侧恢复流程以及 SFU 场景下的特殊处理。文章指出 FlexFEC 通过动态冗余策略提升弱网抗丢包能力,详细解析了编解码器分配、SSRC 映射、包恢复等关键环节,并提供了针对 XR+SFU 场景的调试建议。调试时可重点关注 FEC 包接收与媒体包恢复日志,以验证链路有效性。

HOSTEN的博客 48

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

EMQ X SSL/TLS配置实战:从证书生成到双向认证与深度排错

SSL/TLS协议是保障网络通信安全的基石,它通过在传输层与应用层之间建立加密通道,确保数据在传输过程中的机密性、完整性和身份认证。其核心原理基于非对称加密(如RSA、ECC)进行密钥交换,并结合对称加密实现高效的数据加密传输。在物联网(IoT)领域,MQTT协议作为轻量级的消息传输标准,其安全性高度依赖于底层的TLS实现。EMQ X作为一款高性能的分布式MQTT消息服务器,其SSL/TLS配置的灵活性与复杂性并存,涉及单向/双向认证(mTLS)、证书链管理、密码套件选择等多个关键环节。正确的配置不仅能抵御

weixin_33859231的博客 511

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

上一篇: 基于:Eclipse paho 的MQTT Java客户端实现数据的发送和接收
下一篇: mosquito源码分析和优化
大树叶
博客等级 码龄12年 1171粉丝 664原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值