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

简介: 上篇将3D弹力布局的算法运行在Web Workers后台,这篇我们将进一步折腾,将算法运行到真正的后台:Node.js,事先申明Node.js篇和Web Workers篇一样,在这个应用场景下并不能提高性能,纯粹为了折腾好玩,当然也不会白玩,人生就在折腾中,只有折腾才能真正成长。

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

  

目录
相关文章
|
移动开发 前端开发 HTML5
Twaver-HTML5基础学习(8)拓扑元素(Element)_网元(Element)、节点(Node)
本文介绍了Twaver HTML5中的拓扑元素(Element),包括网元(Element)、节点(Node)和连线(Link)的基本概念和使用方法。文章详细解释了Element的属性和方法,并通过示例代码展示了如何在React组件中创建节点、设置节点属性和样式。
308 1
Twaver-HTML5基础学习(8)拓扑元素(Element)_网元(Element)、节点(Node)
从0开发游戏引擎之3D物体基类Node3D实现
从0开发游戏引擎之3D物体基类Node3D实现
|
4月前
|
JavaScript Unix Linux
nvm与node.js的安装指南
通过以上步骤,你可以在各种操作系统上成功安装NVM和Node.js,从而在不同的项目中灵活切换Node.js版本。这种灵活性对于管理不同项目的环境依赖而言是非常重要的。
1036 11
|
9月前
|
弹性计算 JavaScript 前端开发
一键安装!阿里云新功能部署Nodejs环境到ECS竟然如此简单!
Node.js 是一种高效的 JavaScript 运行环境,基于 Chrome V8 引擎,支持在服务器端运行 JavaScript 代码。本文介绍如何在阿里云上一键部署 Node.js 环境,无需繁琐配置,轻松上手。前提条件包括 ECS 实例运行中且操作系统为 CentOS、Ubuntu 等。功能特点为一键安装和稳定性好,支持常用 LTS 版本。安装步骤简单:登录阿里云控制台,选择扩展程序管理页面,安装 Node.js 扩展,选择实例和版本,等待创建完成并验证安装成功。通过阿里云的公共扩展,初学者和经验丰富的开发者都能快速进入开发状态,开启高效开发之旅。
|
8月前
|
资源调度 JavaScript 前端开发
前端开发必备!Node.js 18.x LTS保姆级安装教程(附国内镜像源配置)
本文详细介绍了Node.js的安装与配置流程,涵盖环境准备、版本选择(推荐LTS版v18.x)、安装步骤(路径设置、组件选择)、环境验证(命令测试、镜像加速)及常见问题解决方法。同时推荐开发工具链,如VS Code、Yarn等,并提供常用全局包安装指南,帮助开发者快速搭建高效稳定的JavaScript开发环境。内容基于官方正版软件,确保合规性与安全性。
7214 23
|
9月前
|
JavaScript 前端开发 数据可视化
【01】Cocos游戏开发引擎从0开发一款游戏-cocos环境搭建以及配置-Cocos Creator软件系统下载安装-node环境-优雅草卓伊凡
【01】Cocos游戏开发引擎从0开发一款游戏-cocos环境搭建以及配置-Cocos Creator软件系统下载安装-node环境-优雅草卓伊凡
519 2
【01】Cocos游戏开发引擎从0开发一款游戏-cocos环境搭建以及配置-Cocos Creator软件系统下载安装-node环境-优雅草卓伊凡
|
9月前
|
弹性计算 JavaScript 前端开发
一键安装!阿里云新功能部署Nodejs环境到ECS竟然如此简单!
一键安装!阿里云新功能部署Nodejs环境到ECS竟然如此简单!
一键安装!阿里云新功能部署Nodejs环境到ECS竟然如此简单!
|
8月前
|
数据库
【YashanDB知识库】安装共享集群时报错:YAS-05721 invalid input parameter, reason: node name invalid
【YashanDB知识库】安装共享集群时报错:YAS-05721 invalid input parameter, reason: node name invalid
|
12月前
|
存储 JavaScript 搜索推荐
Node框架的安装和配置方法
安装 Node 框架是进行 Node 开发的第一步,通过正确的安装和配置,可以为后续的开发工作提供良好的基础。在安装过程中,需要仔细阅读相关文档和提示,遇到问题及时解决,以确保安装顺利完成。
648 58
|
10月前
|
JavaScript
nodejs安装之npm ERR! code CERT_HAS_EXPIREDnpm ERR! errno CERT_HAS_EXPIRED reason: certificate has expired-证书错误通用问题解决方案-优雅草央千澈
nodejs安装之npm ERR! code CERT_HAS_EXPIREDnpm ERR! errno CERT_HAS_EXPIRED reason: certificate has expired-证书错误通用问题解决方案-优雅草央千澈
1574 27