You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React Native/Expo中通过mDNS发现IoT设备的可行方案咨询

如何在Expo/React Native应用中发现mDNS IoT设备

当然可以不用立刻脱离Expo!这里有几个可行的方案,按推荐优先级排序:

1. 用纯JS库 multicast-dns + expo-udp 适配实现

multicast-dns是纯JavaScript的mDNS实现,虽然它默认依赖Node.js的dgram模块,但Expo提供了expo-udp库,它和dgram的API非常相似,可以用来替换依赖,让multicast-dns在Expo环境中运行。

步骤如下:

  • 安装依赖:
    npx expo install expo-udp multicast-dns
    
  • 编写适配代码,替换multicast-dns的底层套接字:
    import UDP from 'expo-udp';
    import mdns from 'multicast-dns';
    
    // 创建Expo UDP套接字
    const socket = new UDP.Socket();
    
    // 初始化mDNS实例,指定自定义的socket实现
    const md = mdns({
      socket: {
        bind: (port, address, callback) => socket.bind(port, address, callback),
        on: socket.on.bind(socket),
        send: (buf, offset, length, port, address, callback) => socket.send(buf, port, address, callback),
        close: socket.close.bind(socket),
        // 按需实现其他dgram方法,如果multicast-dns用到的话
      }
    });
    
    // 开始搜索设备,比如搜索你的IoT设备的服务类型,比如 '_your-service._tcp.local'
    md.on('response', (response) => {
      console.log('发现设备:', response.answers);
      // 在这里处理找到的设备信息
    });
    
    md.query({
      questions: [{
        name: '_your-service._tcp.local',
        type: 'SRV'
      }]
    });
    

2. 使用Expo兼容的社区mDNS模块(无需eject)

如果上面的适配方案太繁琐,可以尝试@react-native-community/mdns,这个模块现在支持通过Expo的config plugin在managed workflow中使用,不需要手动执行react-native link或者eject。

步骤:

  • 安装依赖:
    npx expo install @react-native-community/mdns
    
  • app.json中添加config plugin:
    {
      "expo": {
        "plugins": [
          "@react-native-community/mdns"
        ]
      }
    }
    
  • 然后就可以按照模块文档编写发现代码了,比如:
    import { MDNS } from '@react-native-community/mdns';
    
    // 搜索指定服务类型的设备
    MDNS.search('_your-service._tcp.local').then((devices) => {
      console.log('找到的设备:', devices);
    });
    

3. 最后选择:脱离Expo到Bare Workflow

如果上面的方案都无法满足需求(比如需要更复杂的mDNS功能),再考虑eject到bare workflow,然后使用react-native-zeroconf这类原生模块。不过这一步会失去Expo的一些便利特性,所以建议优先尝试前面的方案。

重要权限配置

不管用哪种方案,都需要配置相应的权限:

  • iOS:在app.jsonios.infoPlist中添加Bonjour服务声明:
    "ios": {
      "infoPlist": {
        "NSBonjourServices": ["_your-service._tcp.local"],
        "NSLocalNetworkUsageDescription": "需要访问本地网络以发现IoT设备"
      }
    }
    
  • Android:在app.jsonandroid.permissions中添加权限:
    "android": {
      "permissions": [
        "ACCESS_NETWORK_STATE",
        "CHANGE_WIFI_MULTICAST_STATE",
        "ACCESS_WIFI_STATE"
      ]
    }
    

内容的提问来源于stack exchange,提问作者José Roberto Canuto Vasconcelo

火山引擎 最新活动