上篇将3D彈力布局的算法運作在Web Workers背景,這篇我們将進一步折騰,将算法運作到真正的背景:Node.js,事先申明Node.js篇和Web Workers篇一樣,在這個應用場景下并不能提高性能,純粹為了折騰好玩,當然也不會白玩,人生就在折騰中,隻有折騰才能真正成長。

核心實作代碼和Web Workers篇基本一緻,唯一差別在于前背景互動的方式上,worker通過postMessage和addEventListener('message' 就可以發送和接收消息,對于真正分離前背景的Node.js自然沒那麼簡單了,我采用了Socket.io通信架構,Socket.io讓長連接配接通信變得無比簡單,和Web Workers的通信幾乎一樣的容易了,Socket.io的用法下圖一目了然:
Node.js背景代碼如下,通過require引入HT和Socket.io相關類庫,io = require('socket.io').listen(8036)建構出一個監聽在8036端口的服務,通過io.sockets.on('connection'等着用戶端頁面來建立的socket通信,通過socket.on('moveMap',監聽用戶端發過來的圖檔節點拖拽變化資訊進行同步,通過 socket.emit('result', result);發送自動布局算法的運算結果push到用戶端。
用戶端的代碼需要通過引入Socket.io用戶端類庫,通過socket = io.connect('http://localhost:8036/')連結伺服器獲得握手連結socket對象,剩下的代碼就是同socket.emit發送用戶端拖拽資訊,以及socket.on監聽伺服器推送過來的自動布局結果:
幾個注意點:
1、首選和Web Workers一樣,跑在Node.js的類庫肯定不能操作window和document之類的頁面特定元素對象,從這點說很多考慮不周全的類庫會把自己限制死隻能在頁面主線程運作,這點HT for Web考慮得很周到,不僅ht.js包括所有ht-forcelayout.js插件都是可運在Web Workers和Node.js的非GUI環境,因為我也常需要ht.js運作在背景直接将DataModel的資料和前台進行JSON的資料格式轉換存儲。
2、Util.js定義的reloadModel函數我增加了this.reloadModel = reloadModel;的邏輯,這樣才能在Node.js背景代碼reloadModel = require("../util.js").reloadModel; 這樣的方式得到該函數進行調用,細節可以參考 http://nodejs.org/api/modules.html 的章節
3、這個例子是有缺陷的,以下視訊播放過程你會發現,我打開了兩個頁面,這樣就會有兩個socket分别連接配接背景Node.js,而Node.js預設是單線程的,如果正在一個請求函數密集運算處理,則其他請求隻能排隊等待處理,這也是視訊中我拖拽一個頁面布局是,另一個頁面無法操作的原因。當然你可以改進demo,采用http://nodejs.org/api/cluster.html的cluster方式,實作真正的背景多核任務處理