小程序开发必备的高级能力之四:mDNS

小编推荐:Fundebug专注于JavaScript、微信小程序、微信小游戏,Node.js和Java实时BUG监控。真的是一个很好用的bug监控费服务,众多大佬公司都在使用。

1、效果图

先瞅一眼效果图。

微信图片_20181217120824.png

2、释义

mDNS:即组播DNS(multicast DNS),使用5353端口,主要实现了在没有传统DNS服务器的情况下使局域网内的主机实现相互发现和通信。(--百度百科)

微信图片_20181217120820.png

这段话什么意思呢?

其实是酱婶的,在客户端和服务端通信过程中(request,socket,websocket,ftp等),我们一般都需要知道对方的域名或者ip/port才能通信。

而在发送请求前,域名最终会经过一个叫DNS服务器的地方解析出相应的ip/port才能通信。

在局域网中,各个设备是没有域名的。此时我们只能通过ip/port来通信,但一般情况下各设备的ip是不固定的,它们是由DHCP分配的,在偶尔的掉线重连之后没准ip就变了,而且你也不知道要连接的设备的ip是多少。

基于此,mDNS登场了,它主要实现了设备间的互相发现。

emmmm,它没有通信功能。通信一般是通过socket来进行。

3、小程序中的mDNS

小程序中的mDNS主要有10个API
其中2个是主动事件,4个监听事件回调和4个取消监听事件回调
他们之间的关系是一一对应的。
而且,除了2个主动事件外,其他8个方法都是传1个回调方法过去

2个主动事件分别是:
1.开始搜寻局域网下的mDNS服务 wx.startLocalServiceDiscovery
2.停止搜索 mDNS 服务 wx.stopLocalSeviceDiscovery

4个监听事件回调分别是:
1.监听mDNS服务发现的事件 wx.onLocalServiceFound
2.监听mDSN服务解析失败的时间 wx.onLocalServiceResolveFail
3.监听mDNS服务离开的事件 wx.onLocalServiceLost
4.监听mDNS 服务停止搜索的事件 wx.onLocalServiceDiscoveryStop

4个取消监听事件回调分别是(目前这4个API无效?不知是否是我调用方式不对。但无所谓,这4个方法就算无效也没什么影响。)
1.取消监听mDNS 服务发现的事件 wx.offLocalServiceFound
2.取消监听mDNS 服务解析失败的事件 wx.offLocalServiceResolveFail
3.取消监听mDNS 服务离开的事件 wx.offLocalServiceLost
4.取消监听mDNS 服务停止搜索的事件 wx.offLocalServiceDiscoveryStop

4、实践

我们实现手动开启和关闭mDNS搜索,并在开启时实现mDNS监听事件的4个方法,在关闭时取消监听mDNS的4个方法。
wxml/wxss就不提,主要js实现如下。

/**
   * 开始搜索
   */
  startDiscovery:function(){
    let that = this
    serviceList = []
    resolveFailList = []
    wx.startLocalServiceDiscovery({
      serviceType:'_http._tcp.',
      success:function(res){
        that.onLocalService()
        
      },
      fail:function(err){
        console.log(err)
      },
      complete:function(){
        console.log('complete')
      }
    })

  },

  /**
   * stopDiscovery
   */
  stopDiscovery:function(){
    let that = this
    wx.stopLocalServiceDiscovery({
      success: function () {
        that.showTips('停止搜索成功','success')
        serviceList = []
        resolveFailList = []
        that.setData({
          lists:[],
          resolveFailList:[]
        })
        that.offLocalService()
        
      },
      fail: function () {
        that.showTips('停止搜索失败,请重试!')
      },
      complete: function () {
        console.log('stopDiscovery complete')
      }
    })
  },

  /**
   * 提示方法
   */
  showTips:function(title='出错啦',icon='none'){
    wx.showToast({
      title: title,
      icon: icon,
      duration:2000
    })
  },

  /**
   * 监听方法合集
   */
  onLocalService:function(){
    let that = this
    // 监听服务发现事件
    wx.onLocalServiceFound(function (obj) {
      console.log(obj)
      serviceList.push(obj)
      that.setData({
        lists: serviceList
      })
    })

    // 监听服务解析失败事件
    wx.onLocalServiceResolveFail(function (obj){
      resolveFailList.push(obj)
      that.setData({
        resolveFailList: resolveFailList
      })
    })

    // 监听服务离开
    wx.onLocalServiceLost(function (obj){
      that.showTips('有服务离开啦');
      console.log(obj)
    })

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

  },

  /**
   * offLocalService
   */
  offLocalService: function () {

    console.log('是否执行此部分数据')
    // 取消监听服务发现事件
    wx.offLocalServiceFound(function () {
      console.log('取消监听服务发现事件 成功')
    })

    // 取消监听服务解析失败事件
    wx.offLocalServiceResolveFail(function () {
      console.log('取消监听 mDNS 服务解析失败的事件 成功')
    })

    // 取消监听服务离开
    wx.offLocalServiceLost(function () {
      console.log('取消监听服务离开事件 成功')
    })

    // 取消监听搜索停止
    wx.offLocalServiceDiscoveryStop(function () {
      console.log('取消监听 mDNS 服务停止搜索的事件 成功')
    })
  },

开始搜索 时正确,如下图。

微信图片_20181217120824.png

但是随后,每次停止搜索后再次开始搜索时,每个设备会被发现了2次。再停止搜索再开启搜索,会被发现3次。经定位,是取消监听的4个方法无效。(现在是2018-12-17 11:36),如下图。

微信图片_20181217120828.png

5、 最佳实践

其实,那4个取消监听的方法就算无效,对我们来说也不是很重要。
上面碰到的问题,无非是多次实现了监听事件而已。基于此,我们至少有2种解决方式。
1、使用statu来判断,不是第一次开启,就不再执行监听事件代码
2、在搜索之前就调用监听事件,开启搜索成功之后不再调用,这样子开启和关闭搜索功能,不和其他方法耦合。

于是,我们改进代码,使用第二种方法来解决这个问题。在onShow()中执行this.onLocalService(),并注释掉开启搜索成功回调里的代码即可。

最后把mdns这部分代码放到了github上。这里

6、其他注意事项

1、mdns只能真机调试
2、主动调用wx.stopLocalSeviceDiscovery()并不会触发wx.onLocalServiceDiscoveryStop事件,该事件在意外停止了搜索时才触发,例如手机屏幕关闭一段时间等

作者:甚时跃马归来
链接:https://www.jianshu.com/p/e66b0d400807
 

关于Fundebug

Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了9亿+错误事件,得到了Google、360、金山软件、百姓网等众多知名用户的认可。欢迎免费试用!

猜你喜欢

转载自blog.csdn.net/qq_40126542/article/details/85276380