基于 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(一)

今天没有延续上一篇讲的内容,穿插一段小插曲,WebSocket 实时数据通讯同步的问题,今天我们并不是很纯粹地讲 WebSocket 相关知识,我们通过 WebGL 3D 拓扑图来呈现一个有趣的 Demo。接下来我们就看看这个实时数据通讯是一个什么样的套路。

我们先来聊聊这次 Demo 的思路吧,首先我要有一个 3D 的拓扑图组件,在上面创建几个节点,然后通过拉力布局(ForceLayout)将这些节点自动布局,但是有一定,需要在不同的网页窗口下,对应节点的位置是一样的,简单地说就是不同网页窗口所呈现的节点布局是一样,而且拖动不同网页窗口中的任意的节点,都将更新所有页面窗口,让所有窗口的呈现都是一样的。

根据上面的思路,我们该如何去规划呢?既然需要实时数据通讯,那么就需要使用 WebSocket,WebSocket 又是什么呢?WebSocket 是 HTML5 一种新的协议,它没有标准的 API,各个实现都有自己的一套 API,在这里我们就不去详细研究 WebSocket 的具体实现,我也讲不了,至少现在讲不了。

在这里我们用比较易上手的 Node.js 的 Socket.IO 做通讯框架,Socket.IO 让长连接通讯变得无比简单,服务器再也不用等待客户端的请求就可以直接给客户端发送消息,根据这样的特性就可以实现数据通讯同步的问题。

我们来写一个最简单的例子,将任何一个客户端发送到服务器的消息,原封不动的转发到所有连接到服务器的客户端,我们来看看要实现这样的一个功能,服务端要怎么设计。

首先我们得搭建一个简易的 web 服务器。

var app = require('express')();
var http = require('http').Server(app);

app.get('/', function(req, res) {
    res.end('<h1>Hello Message!</h1>');
});

http.listen(4000, function() {
    console.log('listening on *:4000');
});

以上的代码的 Node.js 的代码,将这串代码贴到一个 js 文件中,比如命名为 server.js 然后在 Terminal 中 cd 到 server.js 对应的文件夹下,如果 node server.js 后回车,如果发现报了 Cannot find module ‘xxx’ 的字样,那么说明你在当前目录下没有安装程序用到的相关包。那么我们在当前目录下创建一个叫 package.json 的文件,然后把下面的程序拷贝到该文件中,然后在 Terminal 中输入 npm install,等安装完后,就可以正常启动服务器了。

{
  "name": "socket-example",
  "version": "0.0.1",
  "description": "my first socket.io app",
  "dependencies": {
    "express": "^4.10.2",
    "socket.io": "^1.4.8"
  }
}

启动后,你在浏览器上输入 localhost:4000 就可以看到 Hello Message! 的字样。这是最简单的 HTTP 服务器,那么我们如何在上面加上 WebSocket 的功能呢呢?眼尖的同学可能已经发现上面的 package.json 的内容已经包含了 Socket.IO,那么 Socket.IO 要怎么用呢,怎么样才能达到实时数据通讯的效果呢?

var io = require('socket.io')(http);
io.on('connection', function(socket) {
    console.log('a user connected');
    socket.on('disconnect', function() {
        console.log('user disconnected');
    });

    socket.on('message', function(msg) {
        io.emit('message', msg);
    });
});

在 server.js 中加入上面那串代码,就可以实现客户端之间的实时数据通讯问题。但是在浏览器输入 localhost:4000 你看到的是 Hello Message! 的字样,要怎样才能访问到具体的 html 网页内容呢?这个时候就需要稍微修改下我们的服务器了。

app.get('/', function(req, res) {
    res.sendFile(__dirname + '/index.html');
});

也就是将前面提到的 res.end('<h1>Hello Message!</h1>’); 代码换成 res.sendFile(__dirname + ‘/index.html'); 做个页面跳转,从而达到访问具体 html 网页的目的,在这边是是为了满足 Demo 而做的方案,要搭建一个真正的 http 静态服务器肯定不是这样子的,搭建 http 静态服务器我在这边就不介入研究了,大家刚兴趣的话,可以自己到网上搜索学习。

那么客户端该如何实现来展现服务端的实时通讯呢?

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Socket.IO Message</title>
        <style media="screen">
            #send { font-size: 14px; }
            #msgList { list-style-type: none; margin: 10px 0px; padding: 0; }
            #msgList li { padding: 5px 10px; }
            #msgList li:nth-child(odd) { background: #eee; }
        </style>
        <script src="/socket.io/socket.io.js"></script>
        <script>
            var socket = io();
            var init = function() {
                var input = document.getElementById('message'),
                    sendFunc = function() {
                        var msg = input.value;
                        if (!msg) return;
                        socket.emit('message', input.value);
                        input.value = '';
                    };

                input.addEventListener('keyup', function(e) {
                    if (e.keyCode === 13) {
                        sendFunc();
                    }
                });

                var list = document.getElementById('msgList');
                socket.on('message', function(msg) {
                    var li = document.createElement('li');
                    li.innerHTML = msg;
                    list.insertBefore(li, list.childNodes[0]);
                });

                var btn = document.getElementById('send');
                btn.addEventListener('click', sendFunc);
            };
        </script>
    </head>
    <body onload="init();">
        Message: <input id="message" />
        <button type="button" id="send">Send</button><br/>
        <ul id="msgList"></ul>
    </body>
</html>

以上代码就可以做到数据同步了,具体我来解释下。

页面很简单,有一个 input 文本框,和一个 Send 按钮,还有一个 ul 无序列表用来显示用户发送的内容,当用户在 input 文本框中输入内容后,按下 enter 键或者点击 Send 按钮都会想服务器发送文本框中填入的内容,并且服务器会将这条消息原封不动地推送到所有的客户端中,在客户端接收到消息后,就会想 ul 无序列表中填入消息。

这个 Demo 在 http://socket.io/get-started/chat/ 这上面比我讲得清楚,大家可以到上面详细阅读,会理解得更全面一点。

由于篇幅的问题,我今天就介绍到这了,下一篇,我们将重点介绍前面说到的结合 HT for Web 的 3D 拓扑图组件来展现实时数据通讯的效果,让每个客户端都同步操作,效果图如上。

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏沃趣科技

ASM磁盘容量改变的故障处理

某个数据库环境中的ASM磁盘,由于历史原因,全部配置为没有RAID信息的JBOD模式。今天在做产品升级,由于软件需要,需要将原来加入到ASM中每个JBOD的磁盘...

33614
来自专栏自由而无用的灵魂的碎碎念

Windows Server 2008 R2 到Windows 7的改造之路

与windows 7相比,windows server 2008 r2功能更为全面,开发人员也更喜欢使用win server 2008 r2进行开发。

893
来自专栏极客编程

ionic入门之AngularJS扩展

ionic是一个强大的混合式/hybridHTML5移动开发框架,特点是使用标准的HTML、 CSS和JavaScript,开发跨平台(目前支持:Android...

691
来自专栏游戏杂谈

前端开发--优化工具

一般来讲优化前端,涉及到文件优化的有合并、压缩JS和CSS,以及对图片的优化处理,这篇文章的工具很不错,强烈推荐一下。

683
来自专栏小狼的世界

Mac OS X下GnuPlot的安装

Gnuplot是一个科学界广泛使用的作图软件,从Unix软件发展而来,是一款免费软件。因为其强大的作图功能,逐渐也有其他行业的人来维护支持这个软件,使其变的越来...

1001
来自专栏iOS 开发杂谈

iOS直播app之Mac搭建nginx+rtmp服务器

前言 今年移动直播行业的兴起,很多公司都在做直播,转眼间过了大半年了,直播的各种技术相对成熟了起来。今天我们公司也追赶潮流,索性我也转战直播,下面从第一步开始...

1563
来自专栏andychai

前端静态资源缓存策略

页面加载提速是战场,首当其冲要优化的就是 静态资源(js|css) 的加载速度。我们小组去年基于Vue开发了一个积分商城单页面应用。本文旨在与大家分享在单页应用...

1808
来自专栏非著名程序员

我在开发微信小程序中用到的几个不错的库

昨天文章中给大家提到过,在今天的文章中,给大家分享一下,我在开发过程中用到的不错的一些微信小程序的开源库。说道做到,今天就给大家分享。 图片裁剪工具 图片裁剪工...

2689
来自专栏hightopo

基于 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(一)

1152
来自专栏敏捷开发&项目管理

微信小程序开发 (资料汇总,谁还没被坑过?希望助你绕过一些坑)

最近帮人家做一个微信小程序,刚好想熟悉一下。由于牵扯到多用户使用系统,以及数据共享,所以自然架构选择了,客户端和服务器的方式。

1173

扫码关注云+社区