socket数据通信类型
使用 socket.io
模块进行 socket
数据通信,主要有 3 种类型,如表 12.3 所示。

本节将分别介绍 socket
的 3 种数据通信类型。
public通信类型
public
通信类型的示意图如图 12.11 所示。客户 A 向 WebSocket
服务器发送一个事件,WebSocket
所有的客户端(客户A、客户B和客户C)都会接收到这个事件。

实现 public
通信的方法非常简单,直接使用 io.sockets.emit()
方法即可,其语法格式如下:
io.sockets.emit(event, data)
参数 event
表示要发送的事件,参数 data
表示要发送的数据。
【例12.2】使用 socket
发布一则通知。(实例位置:资源包\源码\12\02)
本实例实现在网页上发布一则通知,发布后,自己和其他客户端都能收到该通知。步骤如下。
(1) 新建一个 js.js
文件,该文件中通过在 WebSocket
服务器端使用 io.sockets.emit()
方法向客户端发送一则通知,主要代码如下:
//引入模块
var http = require('http');
var fs = require('fs');
var socketio = require('socket.io');
//创建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 = socketio(server);
io.sockets.on('connection', function (socket) {
//监听客户端的事件receiveData
socket.on('receiveData', function (data) {
console.log("客户端的消息:"+data)
io.sockets.emit('serverData', data); //发送消息(public通信类型)
});
});
(2) 新建客户端页面 index.html
,在该页面中,通过监听服务器端的 serverData
自定义事件,接收服务器端发送的通知并显示。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.bold {
font-weight: bold;
}
ul {
list-style: none;
}
</style>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<form action="">
<fieldset style="width: 360px;margin: 0 auto">
<legend>发布公告</legend>
<textarea id="text" style="width: 320px;height: 90px;margin-left: 10px"></textarea><br>
<div style="text-align: center"><button id="btn" type="button">发送</button></div>
</fieldset>
<ul id="box"></ul>
</form>
<script>
window.onload = function () {
var nick = "";
var box = document.getElementById("box")
const socket = io.connect()
socket.on("serverData", function (data) {
console.log(data)
var html1 = "<span class='bold'>" + data + "</span>"
var li = document.createElement("li")
li.innerHTML += html1
box.append(li)
})
document.getElementById("btn").onclick = function () {
var text = document.getElementById("text").value
socket.emit("receiveData", text)
}
}
</script>
</body>
</html>
运行 js.js
文件,然后在浏览器中多次打开 http://127.0.0.1:52273 网页地址(这里打开了 3 次),此时打开的页面的初始效果相同,如图12.12所示。

在任意一个对话框中,输入一则通知后,单击 “发送” 按钮,此时就可以看到浏览器中的 3 个打开页面中都显示该通知,如图 12.13 所示。

broadcast通信类型
broadcast
通信类型的示意图如图 12.14 所示。客户 A 向 WebSocket
服务器发送一个事件,WebSocket
的客户 A 之外的其他所有客户端都会接收到这个事件。

实现 broadcast
通信的方法非常简单,直接使用 socket.broadcast.emit()
方法即可,其语法格式如下:
socket.broadcast.emit(event, data)
参数 event
表示要发送的事件,参数 data
表示要发送的数据。
【例12.3】实现群发消息功能。(实例位置:资源包\源码\12\03)
本实例实现群发一条消息,而发布者本人看不到该消息,步骤如下。
(1) 新建一个 js.js
文件,该文件中通过在 WebSocket
服务器端使用 socket.broadcast.emit()
方法向客户端群发消息,主要代码如下:
//引入模块
var http = require('http');
var fs = require('fs');
var socketio = require('socket.io');
//创建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 = socketio(server);
io.sockets.on('connection', function (socket) {
//监听客户端的事件clientData
socket.on('receiveData', function (data) {
console.log("客户端的消息:"+data)
socket.broadcast.emit('serverData', data); //发送消息(broadcast通信类型)
});
});
(2) 新建客户端页面 index.html
,在客户端页面中,通过监听服务器端的 serverData
自定义事件,接收服务器端发送的消息并显示。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<form action="">
<fieldset style="width: 200px;margin: 0 auto">
<legend>发布公告</legend>
<textarea id="text" cols="50" rows="10"></textarea><br>
<button id="btn">我写好了</button>
</fieldset>
<div id="box"></div>
</form>
<script>
var box=document.getElementById("box")
const socket = io.connect()
window.onload=function () {
socket.on("serverData", function (data) {
var html=data+"<br>"
box.innerHTML+=html //将获取的信息添加到div中
})
document.getElementById("btn").onclick=function () {
var text = document.getElementById("text").value
socket.emit("receiveData", text) //发送消息
}
}
</script>
</body>
</html>
运行 js.js
文件,然后在浏览器中多次打开 http://127.0.0.1:52273 网页地址(这里打开了 3 次,并且,为方便描述,笔者按照打开顺序依次将它们称为 1 号客户端、2 号客户端和 3 号客户端),此时打开的页面的初始效果相同,如图12.15所示。
接下来,在 1 号客户端的文本框中输入消息后,单击 “我写好了” 按钮,即可将消息群发出去,这时 2 号客户端和 3 号客户端可以接收到该消息,但是 1 号客户端接收不到该消息,效果如图 12.16 所示。


private通信类型
private
通信类型的示意图如图 12.17 所示。客户 A 向 WebSocket
服务器发送一个事件,WebSocket
会向指定的客户端(如客户 C)发送这个事件。

实现 private
通信的方法非常简单,直接使用 io.to(id).emit()
方法即可,其语法格式如下:
io.to(id).emit(event, data)
参数 id
表示客户端的名称,参数 event
表示要发送的事件,参数 data
表示要发送的数据。
【例12.4】实现与好友聊天功能。(实例位置:资源包\源码\12\04)
本实例中模拟的是小B(第一个客户端)与两个好友(后面两个客户端)的聊天过程。具体步骤如下。
(1) 在 WebStorm 中创建一个 js.js
文件,该文件中的 only
事件中的数据是其他好友向小 B 单独发送的内容,而 all
事件中的数据为群发的内容。服务器向客户端发送的事件有 toOne
和 toMany
,它们分别将单独发送的内容和群发的内容发送至客户端。js.js
文件中的代码如下:
//引入模块
var http = require('http');
var fs = require('fs');
var socketio = require('socket.io');
//创建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');
});
//创建列表,用来记录连接的客户端
var list=[]
//创建WebSocket服务器
var io = socketio(server);
io.sockets.on('connection', function (socket) {
list.push(socket.id) //有客户端连接时,将其id保存到列表中
socket.on("only",function(data){
io.to(list[0]).emit('toOne', data) //向指定客户端发送private类型消息
})
socket.on("all",function(data){
io.sockets.emit("toMany",data)
})
})
(2) 新建客户端页面 index.html
,该页面中使用 socket.on()
方法监听 toOne
和 toMany
事件,并将这两个事件中附带的消息内容显示在网页中。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
label {
display: block;
width: 230px;
margin: 10px auto;
}
.bold {
font-weight: bold;
color: red;
}
ul {
list-style: none;
}
</style>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<form action="">
<fieldset style="width: 360px;margin: 0 auto">
<legend>发送消息</legend>
<label>内容:<input id="text" type="text"><br></label>
<div id="sendTo">
<button id="btn" type="button">群发</button>
<button id="btnB" type="button">发送给小B</button>
</div>
</fieldset>
<ul id="box"></ul>
</form>
<script>
window.onload = function () {
var box = document.getElementById("box")
var sendTo = document.getElementById("sendTo")
const socket = io.connect()
socket.on("toOne", function (data) { //显示接收到的私信内容
var html1 = "<span>收到一条私信:</span>"
html1 += "<span class='bold'>" + data + "</span>"
var li = document.createElement("li")
li.innerHTML += html1
box.append(li)
})
socket.on("toMany",function(data){ //显示群发内容
var html1 = "<span>收到一条群发消息:</span>"
html1 += "<span class='bold'>" + data + "</span>"
var li = document.createElement("li")
li.innerHTML += html1
box.append(li)
})
document.getElementById("btn").onclick = function () {
var text = document.getElementById("text").value
socket.emit("all", text) //群发消息
}
document.getElementById("btnB").onclick = function () {
var text = document.getElementById("text").value
socket.emit("only", text) //私发消息
}
}
</script>
</body>
</html>
运行 js.js
文件,3 次打开 http://127.0.0.1:52273 网页地址(按打开顺序,第一个为 “小B” 客户端),此时打开的 3 个网页的效果都如图 12.18 所示。

分别在 3 个浏览器中模拟与好友聊天,效果如图12.19所示。

使用 |