Mosquitto

高性能 MQTT 消息代理服务

欢迎使用 Mosquitto

Mosquitto 是一个开源的 MQTT 消息代理服务,专为物联网、实时数据采集与消息分发场景设计。 通过 Lazycat 平台,您可以一键部署 Mosquitto,无需手动配置容器、卷或网络。

主要功能

协议支持

支持 MQTT 5.0 / 3.1.1 / 3.1 协议,兼容主流客户端

🔐 安全加固

可配置的认证、ACL 与 TLS,加固生产环境访问

💾 持久化

持久化会话与消息,配合 $SYS/# 状态主题方便观测

🧩 轻量高效

低内存占用,可在边缘与云端多种环境运行

📈 可观测性

通过 Lazycat 监控与日志组件快速定位异常

🔄 易于扩展

自带备份目录结构,便于在 Lazycat 中扩展与升级

WebSocket 本地测试

由于浏览器安全限制,HTTPS 页面无法连接到非加密的 WebSocket (ws://)。 您可以下载下方的 HTML 文件,在本地打开进行 WebSocket 连接测试。

本地测试文件

复制以下代码并保存为 mqtt-test.html,然后在浏览器中打开即可测试 WebSocket 连接:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mosquitto WebSocket Test</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 800px; margin: 50px auto; padding: 20px; }
        .panel { background: #f5f5f5; padding: 20px; border-radius: 8px; margin: 20px 0; }
        input, button { padding: 10px; margin: 5px; border-radius: 4px; border: 1px solid #ddd; }
        button { background: #667eea; color: white; cursor: pointer; border: none; }
        button:hover { background: #5568d3; }
        button:disabled { opacity: 0.5; cursor: not-allowed; }
        #messages { background: white; padding: 15px; border: 1px solid #ddd; border-radius: 4px;
                    max-height: 300px; overflow-y: auto; font-family: monospace; font-size: 13px; }
        .msg { padding: 5px; margin: 3px 0; border-left: 3px solid #667eea; background: #f9f9f9; }
        .success { border-left-color: #4caf50; background: #e8f5e9; }
        .error { border-left-color: #f44336; background: #ffebee; }
        .status { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 8px; }
        .connected { background: #4caf50; }
        .disconnected { background: #f44336; }
    </style>
</head>
<body>
    <h1>Mosquitto WebSocket 测试工具</h1>

    <div class="panel">
        <h3><span class="status disconnected" id="status"></span>连接状态: <span id="statusText">未连接</span></h3>
        <div>
            <input type="text" id="broker" placeholder="服务器地址" value="{{SERVER_ADDRESS}}">
            <input type="number" id="port" placeholder="端口" value="9001" style="width: 80px;">
            <button onclick="connect()" id="connectBtn">连接</button>
            <button onclick="disconnect()" id="disconnectBtn" disabled>断开</button>
        </div>
    </div>

    <div class="panel">
        <h3>订阅主题</h3>
        <input type="text" id="subTopic" placeholder="订阅主题" value="test/demo">
        <button onclick="subscribe()" id="subBtn" disabled>订阅</button>
    </div>

    <div class="panel">
        <h3>发布消息</h3>
        <input type="text" id="pubTopic" placeholder="发布主题" value="test/demo">
        <input type="text" id="message" placeholder="消息内容" value="Hello MQTT!">
        <button onclick="publish()" id="pubBtn" disabled>发布</button>
    </div>

    <div class="panel">
        <h3>消息记录 <button onclick="clearMsg()" style="font-size: 12px; padding: 5px 10px;">清除</button></h3>
        <div id="messages"></div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js"></script>
    <script>
        let client = null;

        function log(msg, type = '') {
            const div = document.createElement('div');
            div.className = 'msg ' + type;
            div.textContent = new Date().toLocaleTimeString() + ' - ' + msg;
            document.getElementById('messages').appendChild(div);
            document.getElementById('messages').scrollTop = 999999;
        }

        function updateStatus(connected) {
            const status = document.getElementById('status');
            const text = document.getElementById('statusText');
            status.className = 'status ' + (connected ? 'connected' : 'disconnected');
            text.textContent = connected ? '已连接' : '未连接';
            document.getElementById('connectBtn').disabled = connected;
            document.getElementById('disconnectBtn').disabled = !connected;
            document.getElementById('subBtn').disabled = !connected;
            document.getElementById('pubBtn').disabled = !connected;
        }

        function connect() {
            const broker = document.getElementById('broker').value;
            const port = parseInt(document.getElementById('port').value);
            const clientId = 'mqtt_test_' + Math.random().toString(16).substr(2, 8);

            log('正在连接到 ws://' + broker + ':' + port + '...');
            client = new Paho.MQTT.Client(broker, port, clientId);

            client.onConnectionLost = (res) => {
                updateStatus(false);
                log('连接断开: ' + res.errorMessage, 'error');
            };

            client.onMessageArrived = (msg) => {
                log('[' + msg.destinationName + '] ' + msg.payloadString, 'success');
            };

            client.connect({
                onSuccess: () => {
                    updateStatus(true);
                    log('连接成功!', 'success');
                },
                onFailure: (err) => {
                    updateStatus(false);
                    log('连接失败: ' + err.errorMessage, 'error');
                }
            });
        }

        function disconnect() {
            if (client && client.isConnected()) {
                client.disconnect();
                updateStatus(false);
                log('已断开连接');
            }
        }

        function subscribe() {
            const topic = document.getElementById('subTopic').value;
            if (!topic) return;
            client.subscribe(topic, {
                onSuccess: () => log('已订阅: ' + topic, 'success'),
                onFailure: (err) => log('订阅失败: ' + err.errorMessage, 'error')
            });
        }

        function publish() {
            const topic = document.getElementById('pubTopic').value;
            const msg = document.getElementById('message').value;
            if (!topic || !msg) return;
            const message = new Paho.MQTT.Message(msg);
            message.destinationName = topic;
            client.send(message);
            log('已发送到 [' + topic + ']: ' + msg);
        }

        function clearMsg() {
            document.getElementById('messages').innerHTML = '';
        }

    </script>
</body>
</html>
使用说明
1. 点击"复制代码"按钮复制完整 HTML 代码
2. 保存为 mqtt-test.html 文件
3. 用浏览器打开该文件,服务器地址会自动填充
4. 如需修改服务器地址(如: ),可直接在输入框中编辑
5. 点击"连接"按钮即可测试 WebSocket 连接

配置说明

配置文件位置
容器内路径 : /lzcapp/var/config/mosquitto.conf
宿主机路径 : /data/appvar/cloud.lazycat.app.liu.mosquitto/config/mosquitto.conf

基础配置示例

# 监听端口
listener 1883
listener 9001
protocol websockets

# 允许匿名连接(生产环境建议关闭)
allow_anonymous true

# 持久化
persistence true
persistence_location /mosquitto/data/

# 日志
log_dest stdout
log_type all

启用认证配置

# 禁用匿名
allow_anonymous false

# 使用密码文件
password_file /mosquitto/config/passwd

# 创建用户(在容器内执行)
mosquitto_passwd -c /mosquitto/config/passwd username

常用命令

发布消息

mosquitto_pub -h  -t "test/topic" -m "Hello MQTT"

订阅消息

mosquitto_sub -h  -t "test/topic"

查看系统状态

mosquitto_sub -h  -t "$SYS/#" -v

使用认证

mosquitto_pub -h  -u username -P password -t "test/topic" -m "Hello"

端口说明

端口 协议 说明
1883 MQTT 标准 MQTT 协议端口
9001 WebSocket WebSocket 协议端口(用于浏览器客户端)

快速开始

1 在 Lazycat 平台部署应用

访问 Lazycat 平台,搜索 Mosquitto 应用并一键部署。

2 修改配置(可选)

根据需要编辑配置文件,添加认证、ACL 或 TLS 配置。

3 连接测试

使用上方的 WebSocket 演示或命令行工具测试连接。

4 集成到应用

使用 MQTT 客户端库(如 Paho、MQTT.js)将 Mosquitto 集成到您的应用中。

常见问题

Q: 如何查看服务日志?

在 Lazycat 平台的应用管理页面,点击"日志"标签即可查看实时日志。

Q: 如何配置持久化存储?

在配置文件中设置 persistence truepersistence_location /mosquitto/data/。 数据会自动持久化到 Lazycat 平台的存储卷中。

Q: 支持 TLS/SSL 加密吗?

支持。需要在配置文件中配置证书路径和相关参数。建议使用 Let's Encrypt 生成免费证书。

Q: 如何限制客户端连接数?

在配置文件中添加 max_connections <数量> 参数来限制最大连接数。

相关链接