基於socket.io打造hybrid調試頁面

前言

參考的釘釘調試頁面實現,僅供學習!html

功能爲:前端

PC端編寫代碼,手機端執行node

解決的痛點是:git

避免了調試hybrid應用時重複寫各類測試頁面es6

源碼與示例

源碼github

https://github.com/dailc/node-server-examples/tree/master/node-socketio-hybriddebugweb

運行express

1.`npm install`

2.`npm run serve`啓動`node`服務

3.瀏覽器打開`./test/debugroom.html`頁面

4.開始測試(瀏覽器直接打開或手機掃碼)

注意,手機端連接請確保在同一個網段

注意⚠️,實際狀況請重寫client頁面,讓其支持對於Hybrid容器的APInpm

示例gulp

image

image

原理

原理其實很是簡單,就是HTML5中的websocket,並且爲了方便,還直接使用了成熟的第三方庫socket.io

基本交互以下:

1.先啓動一個node後臺(控制檯),基於`express`和`socket.io`監聽`socket`鏈接

2.打開一個PC端調試頁面,鏈接後臺,建立一個房間(能夠建立N個房間)

3.PC端頁面基於房間號生成對應房間的客戶端地址(每個房間中能夠有`N`個客戶端),並基於地址建立二維碼,方便使用(能夠基於`qrcode.js`等庫)

4.`Hybrid`客戶端掃碼後(或者打開客戶端連接後),客戶端頁面鏈接後臺,根據當前的房間號,在房間中建立客戶端

5.PC端輸入代碼後,點擊執行時,會將代碼文本發送到後臺,而後後臺再推送給客戶端,客戶端經過`eval`便可執行這段代碼,執行完畢後也可經過一樣方式通知PC端

須要注意的是:

  • 服務端是引用的npmsocket.io
  • 客戶端是引用socket.io-client項目中發佈的socket.io.js文件

另外:

  • 後臺程序直接基於es6語法編寫的,而後基於gulp打包成dest文件,實際運行的是dest中的發佈文件,代碼規範接近與airbnb
  • 前端頁面的話比較隨意,樣式還大量用了釘釘本來的樣式,也沒有考慮各類瀏覽器的兼容
  • 爲何說是hybrid調試頁面?由於打造它的核心需求就是用來調試hybridAPI

步驟

因爲篇幅關係(也沒有必要),並不會將全部代碼都介紹一遍,只會介紹一些重點步驟,更多的能夠直接閱讀源碼(源碼中已經足夠清晰)

設計DebugRoom(PC端)和DebugClienthybrid端)

根據交互,PC端和hybrid端都須要和後臺鏈接,所以這裏直接單獨封裝了兩個類

DebuRoom類

房間的定義是:

  • 只有一個socket引用
  • 有一個房間id標識
  • 房間內能夠管理客戶端(增,刪,查)
class DebugRoom {
    // 所屬的房間號
    this._roomId
    // 所持有的socket對象
    this._socket
    // 客戶端持有默認是一個空對象,key是clientid,value是client
    this._clients
    
    id()
    clients()
    socket()
    getClientsCount()
    removeClient(client)
    addClient(client)
    clearClients()
}

DebugClient類

客戶端的定義是:

  • 只有一個socket引用
  • 有一個客戶端id標識
  • 有一個房間id引用,指向對於的房間號(固然其實也能夠是引用DebugRoom對象的)
class DebugClient {
    // 所屬的房間號
    this._roomId
    // 客戶端id
    this._clientId
    // 所持有的socket對象
    this._socket
    
    id()
    roomId()
    socket()
}

設計一些交互接口

先後端交互經過socket.io中定義的事件來,如下是房間以及客戶端和後臺的交互事件接口

通用交互事件

後臺:

// 後臺監聽鏈接,每有一個鏈接時(前端經過`io.connect`),會通知客戶端觸發'open'事件
io.on('connection', ...)

// 後臺監聽關閉鏈接,每當鏈接關閉時(前端直接關閉或調用`socket.disconnect`),會檢測本地房間與客戶端,若是關閉的是客戶端,則移除這個客戶端,對於的房間下的引用也置空,不然若是是房間,移除並關閉房間內全部的客戶端
io.on('disconnect', ...)

房間與客戶端:

// 前臺監聽打開事件,此時,若是是房間,則會通知後臺觸發'create room',不然通知後臺觸發'create client'
socket.on('open', ...)

// 前臺監聽鏈接是否關閉
socket.on('disconnect', ...)

房間與後臺交互事件

後臺:

// 監聽建立房間,若是房間ID合法,則會建立一個新的房間(new DebugRoom)
io.on('create room', ...)
// 監聽房間分發數據,而且將數據轉發給房間內的全部客戶端,通知客戶端觸發'receive dispatch data'事件
io.on('dispatch data', ...)

房間:

// 監聽客戶端建立,每個客戶端加入對應房間時都會通知這個房間
socket.on('client created', ...)
// 監聽客戶端關閉,每個客戶端退出時都會通知這個房間
socket.on('client destroy', ...)
// 監聽客戶端執行,客戶端每執行一次分發數據時,都會通知房間是否執行成功
socket.on('client excuted', ...)

客戶端與後臺交互事件

後臺:

// 監聽客戶端建立,若是房間已存在,而且客戶端id合法,纔會正常建立,建立完後會通知房間觸發'client created'事件
io.on('create client', ...)
// 監聽客戶端響應執行,客戶端執行一次分發數據後,會通知後臺,後臺接收到這個事件後,通知房間觸發'client excuted'事件
io.on('client excute notify', ...)

客戶端:

// 監聽接收分發數據,接收完後會執行數據中的代碼,而且通知後臺是否執行成功,觸發後臺的'client excute notify'事件
socket.on('receive dispatch data', ...)

一些邏輯上的細節

以上流程就是整套程序的基本思路與交互,這裏再補充一些交互細節

  • 用全局的roomsHashclientsHash緩存住全部的房間和客戶端,方便直接查詢
  • 每次建立時,id能夠直接綁定在對於的socket中,這樣更方便
  • 房間和客戶端id最好不要直接使用,能夠進過一次編碼(這樣能夠直接使用中文)
  • 客戶端失聯時,必定要先判斷房間是否以及銷燬,不要重複操做
  • 失去鏈接後,緩存中的引用要及時清除

更多源碼請參考https://github.com/dailc/node-server-examples/tree/master/node-socketio-hybriddebug

附錄

博客

初次發佈2017.11.28於我的博客

http://www.dailichun.com/2017/11/28/socket_hybriddebug.html

參考資料

相關文章
相關標籤/搜索