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