In the previous article, we ran the 3D elastic Layout Algorithm on the Web Workers background. This article will go further and run the algorithm to the real background: Node. js, declare Node in advance. like Web Workers, js does not provide high performance in this application scenario. It is purely for fun and of course not for white play. In this case, life is in the midst of tossing, and it can only grow.
The core implementation code is basically the same as that in Web Workers. The only difference is that the front-end and back-end interaction methods allow worker to send and receive messages through postMessage and addEventListener ('message, for the Node that truly separates the front and back ends. js is naturally not that simple. I use Socket. i/O communication framework, Socket. io makes persistent connection communication extremely simple, and the communication with Web Workers is almost the same, Socket. io usage is clear at a glance:
Node. the js background code is as follows: Introduce HT and Socket through require. io-related class library, io = require ('socket. io '). listen (8036) constructs a service that listens to port 8036 through io. sockets. on ('connection' waits for the socket communication established on the client page, through the socket. on ('movemap', listens to the image node sent from the client to drag and drop the change information for synchronization, through socket. emit ('result', result); sends the calculation result of the Automatic Layout Algorithm to the client.
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); }); });
The client code needs to be introduced through Socket. io client class library, through socket = io. connect ('HTTP: // localhost: 8036/') link to the server to obtain the handshake link socket object, and the remaining code is the same as the socket. emit sends client drag information and socket. automatic Layout result pushed by the on listener server:
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]); } } });
Notes:
1. Like Web Workers, it is preferred to run on Node. js class libraries certainly cannot operate on page-specific element objects such as windows and document. From this point, many poorly-considered class libraries will limit themselves to run only on the main page thread, this HT for Web is very considerate, not only ht. js includes all ht-forcelayout.js plug-ins that are available in Web Workers and Node. js non-GUI environment, because I often need ht. js runs in the background to directly convert and store the DataModel data and the foreground JSON data format.
2. Util. I added this to the reloadModel function defined by js. reloadModel = reloadModel; logic, so that the Node. js background code reloadModel = require (".. /util. js "). reloadModel; this way to get the function to call, details can refer to the chapter of the http://nodejs.org/api/modules.html
3. This example is flawed. During the following video playback process, you will find that I opened two pages, so that two sockets will be connected to the backend Node respectively. js, while Node. by default, js is single-threaded. If it is being processed by intensive operation of a request function, other requests can only be queued for processing. This is also the layout of a page that I drag in the video, another reason why the page cannot be operated. Of course, you can improve the demo by using the clusterformula of http://nodejs.org/api/cluster.htmlto handle real and real subsequent multi-core tasks.