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.json的ios.infoPlist中添加Bonjour服务声明:"ios": { "infoPlist": { "NSBonjourServices": ["_your-service._tcp.local"], "NSLocalNetworkUsageDescription": "需要访问本地网络以发现IoT设备" } } - Android:在
app.json的android.permissions中添加权限:"android": { "permissions": [ "ACCESS_NETWORK_STATE", "CHANGE_WIFI_MULTICAST_STATE", "ACCESS_WIFI_STATE" ] }
内容的提问来源于stack exchange,提问作者José Roberto Canuto Vasconcelo




