微信小程序之获取同一局域网下的设备IP

1,126 阅读2分钟

背景:公司要开发一个微信小程序,需要连接硬件设备,实现微信小程序和硬件通信;有一个需求是要获取到设备 IP,刚开始同事提出可以采用轮询方法,但是同一局域网下有254个 IP,意味着要发送254个请求,而且微信小程序每次最多只能发送10个请求的限制,这么操作下来用户要等到花儿都谢了,感觉不太行的样子。

然后经过我一番 search 后,发现有个叫 mDNS 服务的东西,有了这个,再搭配基础库 2.4.0 提供的 wx.startLocalServiceDiscovery 等一系列 mDNS API,就可以用来获取局域网内提供 mDNS 服务的设备的 IP。

developers.weixin.qq.com/miniprogram…

思路:首先硬件要加入 mDNS 服务,其次要让小程序与设备处在同一局域网下,通过wx.startLocalServiceDiscovery 等一系列 mDNS API 搜索到同一局域网下的设备IP,遍历搜索到的 IP 发送请求,能够成功返回响应的就是目标 IP。

let list = [];

export function getIp() {
  onLocalService();
  startDiscovery();
}

// 搜索局域网下的 mDNS 服务
function startDiscovery() {
  wx.startLocalServiceDiscovery({
    serviceType: '_airplay._tcp',// 服务类型
    success:(res) => {
      console.log('设备仓库:',res);
    },
    fail:(err) => {
      console.log('设备仓库:',err);
    }
  })
}

// 获取设备
function onLocalService() {
  wx.showLoading({
    title: '连接中'
  });
  wx.onLocalServiceFound(function (res) {
    console.log('获取设备:',res);
    if(list.length==0) {
      list.push(res);
    }else {
      list.forEach(item => {
        if(res.ip == item.ip) {
          return;
        }
        list.push(res);
      })
    }
    
    console.log('设备列表:',list);
    // 需要考虑多个设备的情况,找到匹配的ip
    list.forEach(item => {
      if(wx.getStorageSync('request_url')) {
        // 若连接成功,取消搜索设备
        return;
      }
      console.log('检测缓存',wx.getStorageSync('request_url'));
      requestDevice(item.ip);
    })
  })
  // 监听服务解析失败事件
  wx.onLocalServiceResolveFail(function (obj){
    console.log('监听服务解析失败事件',obj);
  })

  // 监听服务离开
  wx.onLocalServiceLost(function (obj){
    console.log('获取设备:',obj);
  })

  // 监听搜索停止
  wx.onLocalServiceDiscoveryStop(function (){
    wx.hideLoading();
    console.log('监听到搜索停止事件');
  })
}

// 向设备发送请求
function requestDevice(url) {
  console.log('url:',url);
  wx.request({
    url: 'http://'+url+'/..',
    header: {
      'content-type': 'none'
    },
    method: 'GET',
    success: (res) => {
      console.log('获取设备ip成功:',res);
    },
    fail: (err) => {
      console.log('请求失败:',err);
    },
    complete: (res) => {
      console.log('获取设备ip:',res);
    }
  })
}