You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo + TypeScript连接MQTT Broker异常问题求助

解决方案

核心问题分析

Node.js 环境支持原生 TCP 套接字,但 Expo/React Native 的 JavaScript 运行时(Hermes/JSC)在移动端无法直接使用裸 TCP 连接 MQTT Broker,必须通过 WebSocket 协议(ws:///wss://)通信。这也是你在 Node 里能正常连接、Expo 里却连接关闭的根本原因。


针对 mqtt 包的修复方案

1. 替换连接协议与端口

将原 mqtt:// 协议改为 ws://(非加密)或 wss://(加密),对应 Broker 的 WebSocket 端口:

  • 常见 Broker 默认端口:EMQX(ws:8083、wss:8084)、Mosquitto(需手动开启 WebSocket 监听)
  • 本地测试时,不要用 localhost,改用电脑的局域网 IP(比如 192.168.1.100),因为 Expo Go 里的 localhost 指向设备本身而非开发电脑。

2. 调整客户端配置 + 清理资源

在 useEffect 中添加必要配置,并在组件卸载时关闭连接避免内存泄漏:

import React, { useEffect } from 'react';
import { View, Text } from 'react-native';
import mqtt from 'mqtt';

export default function MqttTest() {
  useEffect(() => {
    // 用局域网IP+WebSocket端口连接,末尾的/mqtt部分部分Broker需要(比如EMQX)
    const client = mqtt.connect('ws://192.168.1.100:8083/mqtt', {
      clientId: `expo-client-${Math.random().toString(16).slice(2)}`, // 确保客户端ID唯一
      clean: true,
      connectTimeout: 30000,
      reconnectPeriod: 1000,
    });

    client.on('connect', () => {
      console.log('Connected to MQTT broker');
      client.subscribe('test/topic', (err) => {
        if (!err) client.publish('test/topic', 'Hello from Expo');
      });
    });

    client.on('close', () => console.log('Connection to MQTT broker closed'));
    client.on('error', (err) => console.error('MQTT error:', err));

    // 组件卸载时关闭连接
    return () => client.end();
  }, []);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>MQTT Connection Test</Text>
    </View>
  );
}

3. 配置 Broker 开启 WebSocket 监听

以 Mosquitto 为例,修改配置文件添加:

listener 8083
protocol websockets

保存后重启 Broker 服务。


其他库问题说明

1. react-native-mqtt 报错

该库依赖原生模块,Expo Managed Workflow 无法直接使用(需 eject 到 Bare Workflow),且版本陈旧兼容性差,不推荐在 Expo 项目中使用。

2. paho-mqtt 连接关闭

同样是协议/地址问题,需改用 WebSocket 端口,以下是修正后的示例代码:

import React, { useEffect } from 'react';
import { View, Text } from 'react-native';
import Paho from 'paho-mqtt';

export default function PahoMqttTest() {
  useEffect(() => {
    const client = new Paho.Client(
      '192.168.1.100',
      8083,
      '/mqtt',
      `expo-paho-client-${Math.random().toString(16).slice(2)}`
    );

    client.onConnectionLost = (res) => {
      if (res.errorCode !== 0) console.log('Connection lost:', res.errorMessage);
    };

    client.onMessageArrived = (msg) => console.log('Received:', msg.payloadString);

    client.connect({
      onSuccess: () => {
        console.log('Connected via Paho');
        client.subscribe('test/topic');
        const msg = new Paho.Message('Hello from Expo Paho');
        msg.destinationName = 'test/topic';
        client.send(msg);
      },
      onFailure: (err) => console.error('Paho connect failed:', err),
      connectTimeout: 30000,
    });

    return () => client.disconnect();
  }, []);

  return <View><Text>Paho MQTT Test</Text></View>;
}

额外注意事项

  • iOS 端如果使用非加密的 ws://,需在 app.json 中添加 ATS 例外配置:
    "ios": {
      "infoPlist": {
        "NSAppTransportSecurity": {
          "NSAllowsArbitraryLoads": true
        }
      }
    }
    
    生产环境建议改用加密的 wss:// 避免配置 ATS。
  • 确保 Broker 所在网络允许设备访问(无防火墙/端口限制)。

内容的提问来源于stack exchange,提问作者null_voyager

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 12:15:15