博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于HTML5的3D网络拓扑自动布局
阅读量:5955 次
发布时间:2019-06-19

本文共 3236 字,大约阅读时间需要 10 分钟。

上篇将的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方式,实现真正的后台多核任务处理

  

转载于:https://www.cnblogs.com/xhload3d/p/4859755.html

你可能感兴趣的文章
恢复rm删除的文件(ext3
查看>>
我的友情链接
查看>>
账户注销完自动登录账户,并且不需要再点击屏幕的账户头像
查看>>
【Interface&navigation】按钮(29)
查看>>
我要学python之装饰器
查看>>
Extjs4.x (MVC)Controller中refs以及Ext.ComponentQuery解析
查看>>
消息最终一致性解决方案之RabbitMQ实现
查看>>
记录:网络通信协议中的TCP/IP与UDP
查看>>
我的友情链接
查看>>
基于YUM安装与源码编译或二进制多实例安装Mariadb,mysql
查看>>
基于jxl导入导出Excel
查看>>
多线程面试题
查看>>
GLKVector3参考
查看>>
学习:java设计模式—工厂模式
查看>>
CISCO路由器、交换机密码恢复
查看>>
Cgi与php-Cgi以及Fast-Cgi与php-fpm的理解
查看>>
我的友情链接
查看>>
odoo 财务会计相关介绍
查看>>
大型分布式C++框架《四:netio之请求包中转站 上》
查看>>
lnmp之PDO_mysql.so
查看>>