WebSocket网络编程的基本实现
WebSocket
是从 HTML5 开始提供的一种浏览器与服务器间进行通信的网络技术。使用 WebSocket
时,浏览器和服务器只需要做一个握手的动作,然后浏览器和服务器之间就形成了一条快速通道,两者之间就可以直接进行数据的互相传送。
使用 socket.io
模块可以很方便地实现 WebSocket
网络编程,使用之前,首先需要通过 npm
包管理器进行下载和安装,命令如下:
npm install socket.io
上述命令默认下载的是 socket.io
模块的最新版本,如果要下载指定的版本,比如下载 1.x.x
,在上述命令后面添加 @1
即可,即:
npm install socket.io@1
安装 socket.io
模块后,如果要在程序中使用,需要进行引入,代码如下:
var socketio = require('socket.io');
使用 socket.io
模块进行 WebSocket
网络编程时,通常需要 3 个步骤,依次为创建 WebScoket
服务器、创建 WebSocket
客户端、服务器端和客户端的通信,下面分别进行讲解。
WebSocket服务器端实现
创建 WebSocket
服务器时,首先需要借助 http
模块的 createServer()
方法创建一个 Web
服务器;然后导入 socket.io
模块,并在 WebSocket
服务器构造函数中传入创建的 Web
服务器,从而创建一个 WebSocket
服务器;最后监听 connection
事件,判断是否有客户端连接。
socket.io
模块可以监听的服务器端事件如表12.1所示。

例如,下面代码中通过 http
模块创建了一个 Web
服务器,其中读取一个名称为 index.html
的客户端文件;然后使用 socket.io
模块创建一个 WebSocket
服务器,为 WebSocket
服务器设置 connection
监听事件,当用户在 WebSocket
客户端发起 socket
请求时,会触发该事件,监听是否有客户端连接。代码如下:
var fs = require("fs")
var http = require("http");
var server = http.createServer(function (req, res) { //创建Web服务器
if (req.url == "/") {
//读取客户端文件
fs.readFile("index.html", function (err, data) {
res.end(data);
});
}
});
server.listen(52273, function (socket) {
console.log("监听地址在:http://127.0.0.1:52273")
});
//创建WebSocket服务器
var io = require('socket.io');
io = io(server);
//监听客户端连接
io.sockets.on("connection", function (socket) {
console.log("1个客户端连接了");
});
运行上面代码,效果如图12.1所示。

由于上面示例中没有编写客户端代码,即没有客户端连接,因此控制台没有显示 “1个客户端连接了”。 |
WebSocket客户端实现
创建 WebSocket
客户端时,需要加载 socket.io
客户端代码文件,即 socket.io.js
,然后通过 socket.io
模块中的全局对象 io
的 connect()
方法来向服务器端发起连接请求。connect()
方法的语法格式如下:
io.connect(url)
参数 url
为可选参数,表示要连接的 WebSocket
服务器地址,其可以是 WebSocket
服务器的 http
完整地址,也可以是相对路径,如果省略,则表示默认连接当前路径。
例如,在 12.1.1 节的示例代码中,可以看到使用 http
模块创建的 Web
服务器中读取了一个 index.html
客户端文件,该文件中主要引入 socket.io.js
客户端代码文件,并使用全局对象 io
的 connect()
方法向服务端发起连接请求。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
<h2 style="color:red;text-align: center;margin: 20px auto">我是你们朝思暮想的客户端index.html</h2>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io.connect();
</script>
</body>
</html>
编写完 index.html
客户端文件后,再次运行 12.1.1 节中编写的服务器端文件,并单击运行结果中的链接 http://127.0.0.1:52273 ,效果如图12.2所示。
此时,再次返回控制台,可看到控制台发生变化,效果如图12.3所示。
图12.3是连接一个客户端时控制台的运行效果,如果在浏览器中多次打开 http://127.0.0.1:52273 地址,会发现每打开一次,控制台就会显示一次 “1个客户端连接了”,图 12.4 为打开 3 个客户端网页时的控制台的效果。



上面代码中,在客户端文件中引入了一个 |

服务器端和客户端的通信
创建了服务器端和客户端以后,就可以在服务器端和客户端之间传输数据了。socket.io
模块使用事件的方式进行数据传输,其中,socket.io
可以监听的服务器端事件在 12.1.1 节已经介绍过,具体可参见表 12.1,而其可以监听的客户端事件如表 12.2 所示。

要实现监听和发送事件,同样使用 on()
方法和 emit()
方法,具体如下。
-
on()
:监听socket
事件。 -
emit()
:发送socket
事件。
【例12.1】实现服务器端与客户端之间的通信。(实例位置:资源包\源码\12\01)
本实例需要创建的文件有 js.js
文件(服务器端代码)和 index.html
文件(客户端代码)。具体步骤如下。
(1) 编写 js.js
文件,该文件中首先引入相关模块,然后创建 Web
服务器与 WebSocket
服务器,使用 on()
方法监听 connection
事件,在有客户端连接时,继续监听是否有客户端发送的 clientData
事件,该事件是客户端自定义的一个事件,如果监听到该事件,则输出客户端传输的数据,并使用 emit()
方法向客户端发送一个自定义的 serverData
事件。js.js
文件如下:
//引入模块
var http = require('http');
var fs = require('fs');
//创建Web服务器
var server = http.createServer(function (request, response) {
//读取index.html
fs.readFile('index.html', function (error, data) {
response.writeHead(200, {'Content-Type': 'text/html'});
response.end(data);
});
}).listen(52273, function () {
console.log('服务器监听地址在 http://127.0.0.1:52273');
});
//创建WebSocket服务器
var io = require('socket.io')(server);
io.sockets.on('connection', function (socket) {
console.log('客户端已连接!');
//监听客户端的事件clientData,该事件在客户端定义
socket.on('clientData', function (data) {
//显示客户端发来的数据
console.log('客户端发来的数据是:', data);
//向客户端发送serverData事件和数据
socket.emit('serverData', "谢谢,同乐同乐");
});
});
(2) 编写 index.html
文件,在该文件中生成 socket
对象,然后使用其 on()
方法监听服务器端发送的 serverData
事件,如果监听到,输出传输的数据;然后为按钮创建一个点击事件,该点击事件中,获取文本框中输入的文本内容,并使用 emit()
方法向服务器端发送一个自定义的 clientData
事件。index.html
文件中的代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="/socket.io/socket.io.js"></script>
</head>
<body onload="start()">
<fieldset>
<legend>发送消息</legend>
<div><label for="text">发送内容:</label><input type="text" id="text"/></div>
<div><input type="button" id="button" value="确定"/></div>
</fieldset>
</body>
<script>
//向服务器端发起连接请求
var socket = io.connect();
function start() {
//监听服务器端的事件和数据
socket.on('serverData', function (data) {
alert("来自服务器端的消息"+"\n" + data);
});
//创建表单点击事件
document.getElementById('button').onclick = function () {
//获取表单数据
var text = document.getElementById('text').value;
//向服务器端发送事件clientData和数据
socket.emit('clientData', text);
};
};
</script>
</html>
运行 js.js
文件,初始效果如图 12.6 所示。

打开浏览器,在地址栏中输入 http://127.0.0.1:52273 ,并按 Enter 键,此时浏览器中将显示如图 12.7 所示的 index.html
客户端页面,而服务器端控制台中会显示客户端已连接,如图12.8所示。


在浏览器中的文本框中输入 “你好”,并单击 “确定” 按钮,此时,会弹出对话框显示从服务器端发来的消息,同时服务器端控制台也会接收到从客户端发来的 “你好” 消息,如图 12.9 和图 12.10 所示。

