|
接上一回TWaver HTML5 + Node.js + express + socket.io + redis(四), 这一篇您将了解到
1. 如何保存更改后的拓扑数据 (包括新增的, 修改的, 删除的)
2. 如何广播更改后的拓扑数据 (仅仅广播更改的数据)
下面是mac和iphone上的效果图, mac或iphone上的修改都将及时互相同步:
一. 先来看后台如何实现
后台需要做两件事情: 保存修改以及广播修改; 其中修改又分为是新增, 修改, 还是删除. 保存修改很容易, 无非就是对数据库的增删改, 广播数据也很容易, 调用Socket.emit之前, 先设置广播标记就ok了: Socket.broadcast.emit. 而且这个广播只会通知其他客户端, 发送这个广播的客户端不会收到广播, 这正好是我们需要的, 所以后台代码就好写了:
添加保存数据的socket.io监听, 里面保存数据后, 广播之:
1 //保存数据
2 client.on('saveData', function (datas) {
3 if (!datas) {
4 return;
5 }
6 //保存新增网元
7 save(datas.add);
8 //保存修改网元
9 save(datas.change);
10 //删除网元
11 remove(datas.remove);
12 //广播更新
13 client.broadcast.emit('broadcast', datas);
14 });
保存数据的函数如下:
1 //保存网元
2 function save (datas) {
3 if(!datas){
4 return;
5 }
6 var elements = {};
7 for (var i=0,n=datas.length,data; i 如果有新增网元, 则将新增网元加上add标记, 如果有网元被删除, 则存入map中
1 //添加数据容器更改监听器
2 box.addDataBoxChangeListener( function (e) {
3 //如果正在响应广播更新,则返回
4 if (isChanging) {
5 return;
6 }
7 //设置保存数据标记
8 needSave = true;
9 if (e.kind === 'add') {
10 //将新增的节点置上add标记
11 e.data.setClient('add', true);
12 } else if (e.kind === 'remove') {
13 //如果网元没有新增标记, 则存储到被删除网元列表中
14 if (!e.data.getClient('add')) {
15 //存储被删除网元
16 removedElements[e.data.getId()] = e.data;
17 }
18 }
19 });
iii> 启动定时器, 保存更改
定时器代码如下:
1 //自动保存
2 function setAutoSave (value) {
3 if(value){
4 //定时器,每隔1秒钟保存修改
5 timer = setInterval(function(){
6 save();
7 }, 1000);
8 }else{
9 window.clearTimeout(timer);
10 }
11 }
保存数据代码如下, 需要注意的是, 得到要添加和被修改的网元后, 需要将其add和change标记置为false, 以避免重复保存:
1 //保存数据
2 function save () {
3 //如果无数据添加、修改、删除,则直接返回
4 if(!needSave){
5 return;
6 }
7
8 var add = [];
9 var change = [];
10 var remove = [];
11 isChanging = true;
12 box.forEach(function(data){
13 //新增的网元
14 if(data.getClient('add')){
15 add.push(toData(data));
16 }
17 //修改的网元
18 else if(data.getClient('change')){
19 change.push(toData(data));
20 }
21 //清除网元新增和修改标记
22 data.setClient('add', false);
23 data.setClient('change', false);
24 });
25 isChanging = false;
26 //删除的网元
27 for(var id in removedElements){
28 remove.push(toData(removedElements[id]));
29 }
30
31 if(add.length == 0 && change.length == 0 && remove.length == 0){
32 return;
33 }
34
35 //初始化待删除数据
36 removedElements = {};
37 //还原保存数据标记
38 needSave = false;
39 //构造更新数据
40 var datas = {};
41 if(add.length != 0){
42 datas.add = add;
43 }
44 if(remove.length != 0){
45 datas.remove = remove;
46 }
47 if(change.length != 0){
48 datas.change = change;
49 }
50 socket.emit('saveData', datas);
51 }
从网元获取要持久化的数据代码如下:
1 //从网元获取持久化数据
2 function toData (element) {
3 if(element instanceof twaver.Node) {
4 return {
5 id: element.getId(),
6 name: element.getName(),
7 location: element.getLocation()
8 };
9 } else {
10 return {
11 id: element.getId(),
12 name: element.getName(),
13 from: element.getFromNode() ? element.getFromNode().getId() : null,
14 to: element.getToNode() ? element.getToNode().getId() : null
15 };
16 }
17 }
2. 响应广播更新
分为新增, 删除以及修改三种情况, 其中很重要的是在做这些事情之前先设置isChanging为true, 以防止重复广播更新
1 //响应广播更新
2 function onBroadcast (data) {
3 if (!data) {
4 return;
5 }
6 //设置响应广播更新标记,防止重复更新
7 isChanging = true;
8 var i, c, add=data.add, change=data.change, remove=data.remove;
9 //添加节点
10 if (add) {
11 for (i=0,c=add.length; i |
|