3D拓扑自动布局之Node.js篇

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我和未来有约会

Silverlight第三方控件专题

这里我收集整理了目前网上silverlight第三方控件的专题,若果有所遗漏请告知我一下。 名称 简介 截图 telerik 商 RadC...

4385
来自专栏转载gongluck的CSDN博客

cocos2dx 打灰机

#include "GamePlane.h" #include "PlaneSprite.h" #include "BulletNode.h" #include...

7066
来自专栏C#

DotNet加密方式解析--非对称加密

    新年新气象,也希望新年可以挣大钱。不管今年年底会不会跟去年一样,满怀抱负却又壮志未酬。(不过没事,我已为各位卜上一卦,卦象显示各位都能挣钱...)...

5898
来自专栏张善友的专栏

Silverlight + Model-View-ViewModel (MVVM)

     早在2005年,John Gossman写了一篇关于Model-View-ViewModel模式的博文,这种模式被他所在的微软的项目组用来创建Expr...

3278
来自专栏魂祭心

原 canvas绘制clock

5074
来自专栏java 成神之路

使用 NIO 实现 echo 服务器

5567
来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

5228
来自专栏Ceph对象存储方案

Luminous版本PG 分布调优

Luminous版本开始新增的balancer模块在PG分布优化方面效果非常明显,操作也非常简便,强烈推荐各位在集群上线之前进行这一操作,能够极大的提升整个集群...

3655
来自专栏一个爱瞎折腾的程序猿

sqlserver使用存储过程跟踪SQL

USE [master] GO /****** Object: StoredProcedure [dbo].[sp_perfworkload_trace_s...

2850
来自专栏我和未来有约会

Kit 3D 更新

Kit3D is a 3D graphics engine written for Microsoft Silverlight. Kit3D was inita...

2926

扫码关注云+社区