前言

静态网页的时代已经过去了。现在,用户想要动态内容的,像 App 一样体验的页面。并且,页面应该能够自动更新,而不是让用户自己去按 F5 然后重新加载整个页面。当然,这些需求大部分能够通过 JavaScript 的异步请求来实现。但是,如果现在服务器端有了新的数据,你该如何更新你的应用呢?

你可以通过 AJax 轮询的方式,但是这有很多弊端,比如占用大量带宽,占用大量服务器时间来处理这些不必要的请求,同时,这也给了心怀不轨的人 DDos 你服务器的机会,这些弊端都会让你的服务器变得巨慢。好在现在的 Web 技术发展得真的很快,这些问题都可以在迭代中出现了新的解决方案,那就是 WebSocket

WebSocket 允许我们在 Web 客户端和服务器之间,建立一条有状态的链接。因此我们能够双向地传递数据。由于减少了大量的请求以及链接建立的损耗,WebSocket 比标准的 HTTP 请求要高效得多。

但不幸的是,WebSocket 在不同的浏览器上有一些差别,所以要做到跨浏览器地开发会有一些困难。而且,要知道,在一些老的浏览器上是不支持这项新技术的,这个时候我们又该怎么办?我们需要某种跨浏览器的 WebSocket 实现封装,他支持不同浏览器的 WebSocket 实现,并且在那些老旧的、不支持 WebSocket 的浏览器上,能够回退到传统方式运行,从而保证我们的应用能够稳定运行。Scoket.io 便是这么一个库,它不仅实现了以上所说的所有这些功能,而且还提供了很优美的 API,以及一些额外的实用功能。

安装

Socket.io 由两个部分组成:服务端和客户端,都使用 JavaScript 实现。我默认你已经安装了 Node.js 以及 NPM(如果没有,那你可以在网上找到成吨的教程)。

新建一个目录来存放服务端的代码然后运行 `npm package.json 文件。下一步,通过下面的命令将 Socket.io 添加到你的项目:

1
npm install --save socket.io

当然,我们也需要 express 框架来提供服务器的实现支持(当然你也可以用原生的方式)。安装也很简单:

1
npm install --save express

启动一个回传服务器(Echo Server)

那让我们从一个简单的例子开始吧。

我觉得,一个回传服务器应该足够简单也足够有效的来向你展示 Socket.io 如何使用,你也可以基于这个示例做出更加复杂的项目。

新建一个名为 server.js 的文件并且将下面的代码复制进去:

1
var http = require('http')
2
var express = require('express')
3
var socketio = require('socket.io')
4
var app = express(server)
5
var server = http.Server(app)
6
var io = socketio(server)
7
8
app.get('/', function(req, res){
9
  res.sendFile(__dirname + '/index.html')
10
});
11
12
io.on('connection', function(socket){
13
  socket.on('echo', function(data){
14
    socket.emit('echo', data);
15
  });
16
});
17
18
server.listen(8080);

在开始的3行,我们 import 了一些需要用到的库。然后我们创建了一个 HTTP 服务器以及一个 express 应用,这样可以让我们更方便地管理路由。你可以点击了解更多关于 Express 的知识。同样,我们需要创建一个 Socket.io 的实例,并且将其分配给服务器,这样我们就能够使用 WebSocket 来进行通信了。

在下面的一行中,我使用了 express 来定义一个 / 路由,也就是根路由,一般用来返回我们的 index.html 文件的内容。然后,我使用了之前创建的 Socket.io 实例来监听连接请求事件。任何时候,只要有人通过 Socket.io 连接上本服务器,就会触发这个事件,然后调用回调函数。在回调函数中,我们使用了这个 socket 连接,通过这个连接,我们既能够从中读取数据也能够向其发送事件信息。

现在,我们来监听 echo 事件,并且在收到信息的时候,将信息原封不动的转发回去,主意,这里的 echo 事件名使我们自定义的,我们也可以不用主动定义,只是定义后能更方便的管理这些事件。

最后一行就很简单了,在本机的 8080 端口上启动了这个服务器。

客户端代码

在本地创建一个名为 index.html 的文件,然后将下面的代码粘贴进去:

1
<!DOCTYPE html>
2
<html>
3
  <head>
4
    <meta charset="utf-8" />
5
    <title>Echo server</title>
6
    <script src="socket.io/socket.io.js"></script>
7
    <script type="text/javascript">
8
      var socket = io();
9
      socket.on('echo', function(data){
10
        console.log(data);
11
      });
12
      socket.emit('echo', 'this is a message');
13
    </script>
14
  </head>
15
  <body>
16
  </body>
17
</html>

你需要做的第一件事情便是引用 Socket.io 的库文件。这个文件是运行在我们的 Node.js 服务器上的。我这里是直接在 HTML 文件里面写的 JavaScript,为了方便展示,你在真正项目中可不要这样做。

在代码中,我通过 io() 这个方法创建了一个 socket 连向服务器。然后,我触发了 emmit 事件,并且传递了一个 test 字符串作为负载。现在,我们只需要用 node server.js 来启动我们的服务器程序,并且在浏览器中打开 http://localhost:8080/。你应该变能够在控制台中看到 this is a message 字样的输出。

总结

我认为,对于一个开发者来说,需要具备两项特质,一个是快速学习适应新技术的能力,第二个便是总是选择合适的工具完成任务。

Socket.io 真的非常好用也很简单。它让我们能够轻松地在几乎任何应用中享受 WebSocket 带来的好处。它值得被你放进工具集😼。