1. 程式人生 > >小程式開發必備的高階能力之四:mDNS

小程式開發必備的高階能力之四: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、金山軟體、百姓網等眾多知名使用者的認可。歡迎免費試用!