上篇将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到客户端。
io = require('socket.io').listen(8036); ht = require('ht.js').ht; require("ht-forcelayout.js"); reloadModel = require("util.js").reloadModel; io.sockets.on('connection', function (socket) { var dataModel = new ht.DataModel(), forceLayout = new ht.layout.Force3dLayout(dataModel); forceLayout.onRelaxed = function(){ var result = {}; dataModel.each(function(data){ if(data instanceof ht.Node){ result[data._id] = data.p3(); } }); socket.emit('result', result); }; forceLayout.start(); socket.on('moveMap', function (moveMap) { dataModel.sm().cs(); for(var id in moveMap){ var data = dataModel.getDataById(id); if(data){ data.p3(moveMap[id]); dataModel.sm().as(data); } } }); socket.on('reload', function (data) { reloadModel(dataModel, data); }); });
客户端的代码需要通过引入Socket.io客户端类库,通过socket = io.connect('http://localhost:8036/')链接服务器获得握手链接socket对象,剩下的代码就是同socket.emit发送客户端拖拽信息,以及socket.on监听服务器推送过来的自动布局结果:
g3d.mi(function(evt){ if(evt.kind === 'betweenMove'){ moveMap = {}; g3d.sm().each(function(data){ if(data instanceof ht.Node){ moveMap[data._id] = data.p3(); } }); socket.emit('moveMap', moveMap); } }); socket = io.connect('http://localhost:8036/'); socket.on('result', function (result) { for(var id in result){ var data = dataModel.getDataById([id]); if(data && !g3d.isSelected(data)){ data.p3(result[id]); } } });
几个注意点:
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方式,实现真正的后台多核任务处理
操作视频如下: http://v.youku.com/v_show/id_XNjc1MjY2ODE2.html
相关推荐
网络拓扑自动布局算法几篇比较实用的算法论文,写的还可以,自己留做备份
拓扑排序与关键路径.pptx拓扑排序与关键路径.pptx拓扑排序与关键路径.pptx拓扑排序与关键路径.pptx拓扑排序与关键路径.pptx拓扑排序与关键路径.pptx拓扑排序与关键路径.pptx拓扑排序与关键路径.pptx拓扑排序与关键...
3D拓扑优化程序matlab,3d拓扑软件,matlab源码.zip
3D拓扑优化程序matlab,3d拓扑软件,matlab源码.rar
利用d3.js插件实现动态拓扑图,动态增加节点,删除节点,结合拖拽操作,实现一个简单的演示
针对现有网络拓扑图布局算法多以节点分布均匀为目标,没有考虑边的布局,可能会导致生成的拓扑图中边布局不清晰,提出一种基于扩展力学模型的网络拓扑图布局算法。该算法通过引入点边斥力保证边布局清晰,通过节点...
jsPlumb是一个强大的JavaScript连线库,它可以将html中的元素用箭头、曲线、直线等连接起来,...它同时支持jQuery+jQuery UI、MooTools和YUI3这三个JavaScript框架,十分强大。大家可以在官网的Demo中看看它的功能。
利用d3.js插件实现动态拓扑图,动态增加节点,删除节点,结合拖拽操作,实现一个简单的演示利用d3.js插件实现动态拓扑图,动态增加节点,删除节点,结合拖拽操作,实现一个简单的演示
本demo利用jTopo技术,巧妙地将网络中的计算机等设备连接起来形成拓扑图。拓扑图给出网络服务器、工作站的网络配置和相互间的连接,非常试用于想要展示网络物理结构的项目使用
基于网络化数据挖掘的拓扑布局算法研究.pdf
利用go.js绘制的流程图,或可绘制拓扑图,内含html、go.js破解版。以及go.js绘制流程图的整理,注释
echart拓扑图单节点拖拽.zip
拓扑排序拓扑排序应用系统java.zip拓扑排序应用系统java.zip拓扑排序应用系统java.zip
能生成拓扑图的javascript类库.zip
主要针对拓扑优化结果的难以加工,为了实现设计加工一体化,提出一种类似3D打印的技术思想
组网拓扑:静态端口拓扑.doc
3D拓扑优化算法,经典169行代码,MATLAB语言
《点集拓扑学》期末复习.pdf
路由与交换技术综合实例