客户端分组的实现
除了 12.2 节中所讲的 3 种常规通信类型外,在服务器端向客户端发送消息时,还可以对要接收消息的客户端进行分组,下面进行讲解。
创建分组
使用 socket.io
模块实现客户端分组功能时可以通过 socket.join()
方法进行分组,其语法格式如下:
socket.join(room)
参数 room
表示分组的组名。
例如,下面代码创建了两个分组:group1
和 group2
:
socket.on('group1', function (data) {
socket.join('group1');
});
socket.on('group2',function(data){
socket.join('group2');
});
一个客户端可以进入多个分组。 |
退出分组
客户端能够进入分组,同样也可以退出分组,退出分组使用 socket.leave()
方法实现,其语法格式如下:
socket.leave(data.room);
其中,data
为要退出分组的客户端;room
为要退出的分组的组名。
例如,下面代码使指定用户(由客户端传递的数据 data
提供)退出 group2
分组:
socket.on('leavegroup2', function (data) {
var room="group2"
socket.leave(data.room);
io.sockets.in('group2').emit('leave2', data);
});
向分组中的用户发送消息
向分组中的用户发送消息时,可以分为两种情况。第一种情况是,分组中的所有人(包括自己)都可以接收到消息,这时可以使用 io.sockets.in().emit()
方法,其语法格式如下:
io.sockets.in(room).emit(event,data)
第二种情况是,分组中除自己以外的所有人都可以接收该消息,这时可以使用 io.sockets.broadcast.to().emit()
方法,其语法格式如下:
io.sockets.broadcast.to(room).emit(event,data)
参数 room
表示接收该消息的分组的组名,参数 event
表示要发送的事件,参数 data
表示要发送的数据。
【例12.5】实现进群通知和退群通知。(实例位置:资源包\源码\12\05)
大家知道无论 QQ 群还是微信群,当有新用户进群时,所有群成员都能接收到进群通知,而在退群时,群内的管理员可以收到退群通知。本实例将模拟并升级该功能,实现用户进群或者退群时所有群成员都可以收到通知的功能。步骤如下。
(1) 创建 socket
服务器端 js.js
文件,在服务器端监听的事件有 group1
、group2
、leavegroup1
和 leavegroup2
,分别表示客户端进入 group1
分组、客户端进入 group2
分组、客户端离开 group1
分组和客户端离开 group2
分组,在监听到相应的事件发生时,分别向相应的分组内发送进入和离开的通知消息。代码如下:
//引入模块
var fs = require('fs');
//创建服务器
var server = require('http').createServer();
var io = require('socket.io')(server);
server.on('request', function (request, response) {
//读取客户端文件
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');
});
//监听connection事件
io.sockets.on('connection', function (socket) {
//创建分组名称
var roomName = null;
//监听客户端进入group1分组
socket.on('group1', function (data) {
socket.join('group1');
io.sockets.in('group1').emit('welcome1', data);
});
//监听客户端进入group2分组
socket.on('group2', function (data) {
socket.join('group2');
io.sockets.in('group2').emit('welcome2', data);
});
//监听客户端离开group1分组
socket.on('leavegroup1', function (data) {
var roomName="group1"
socket.leave(data.room);
io.sockets.in('group1').emit('leave1', data);
});
//监听客户端离开group2分组
socket.on('leavegroup2', function (data) {
var roomName="group2"
socket.leave(data.room);
io.sockets.in('group2').emit('leave2', data);
});
});
(2) 新建客户端页面 index.html
,在该页面中定义一个 show()
函数,用来以指定的格式显示进群和退群通知;然后分别监听服务器端发送的进入和离开事件,并调用 show()
函数显示相应的信息;另外,在客户端页面中,需要使用 socket.emit()
方法向服务器端发送 group1
、group2
、leavegroup1
和 leavegroup2
这 4 个事件,以便让服务器端进行监听。index.html
页面的关键代码如下:
<script src="/socket.io/socket.io.js"></script>
<script>
window.onload = function () {
// 声明变量.
var nickname = ""
var socket = io.connect();
// 监听事件
socket.on("welcome2", function (data) {
show(2, "进入", data) //客户进入2群
})
socket.on("welcome1", function (data) {
show(1, "进入", data)//客户进入1群
})
socket.on("leave1", function (data) {
show(1, "退出", data) //客户离开1群
})
socket.on("leave2", function (data) {
show(2, "退出", data)//客户离开2群
})
document.getElementById("group1").onclick = function () {
if (nickname == "") {
setName()
}
socket.emit("group1", nickname) //发送进入1群事件
}
document.getElementById("group2").onclick = function () {
if (nickname == "") {
setName()
}
socket.emit("group2", nickname) //发送进入2群事件
}
document.getElementById("leavegroup1").onclick = function () {
socket.emit("leavegroup1", nickname)//发送离开1群事件
}
document.getElementById("leavegroup2").onclick = function () {
socket.emit("leavegroup2", nickname) //发送离开2群事件
}
document.getElementById("setName").onclick = function () {
setName()
}
function setName() {
var name = document.getElementById("name")
if (name.value == "") {
alert("请设置昵称")
}
else {
nickname = name.value
document.getElementById("none").style.display = "none"
}
}
function show(room, out, data) {
var box = document.getElementById("box" + room)
box.innerHTML += "<li><span class='red'>" + data + "</span><span>" + out + "</span><span>本群</span></li>"
}
};
</script>
</head>
<body>
<fieldset>
<legend>进群</legend>
<label id="none"><span>设置昵称:</span><input type="text" id="name" style="">
<button type="button" id="setName">设置名称</button>
</label>
<div class="btnbox">
<button type="button" id="group1">进入1群</button>
<button type="button" id="group2">进入2群</button>
<button type="button" id="leavegroup1">退出1群</button>
<button type="button" id="leavegroup2">退出2群</button>
</div>
<div>
<ul id="box1">
<p>客户1群</p>
</ul>
<ul id="box2">
<p>客户2群</p>
</ul>
</div>
</fieldset>
运行 js.js
文件,然后分别打开 3 次 http://127.0.0.1:52273 网页地址,其初始效果如图 12.20 所示,依次在浏览器中设置昵称,设置昵称后的效果如图 12.21 所示。


在 3 个打开的页面中分别单击进群和退群的按钮,相应群中的客户端即可显示进群或者退群的消息,效果如图 12.22 所示。
