Nodejs中socket.io的同步问题
Nodejs中socket.io的同步问题
function broadcastEvents(evt, args) { // convert args to array args = args ? Array.prototype.slice.call(args) : []; console.log(evt, args); args.unshift(evt); console.log(args); var audience = broadcast.audience; for (var audId in audience) audience[audId].emit.apply(audience[audId], args); } socket.onEvent = function (evt, func) { socket.on(evt, function () { // If func return true, broadcast it if (func.apply(this, arguments)) broadcastEvents(evt, arguments); }); }; socket.onEvent(‘draw circle’, function (x, y, color, width) { canvas.drawing = { type: ‘circle’, color: color, width: width, points: [{x: x, y: y}] }; return true; });
在 Node.js 中使用 socket.io
进行实时通信时,经常会遇到同步问题。特别是在需要广播事件给多个客户端时,确保所有操作按预期顺序执行是非常重要的。
以下是一个示例代码,展示了如何处理 socket.io
的同步问题,并通过广播事件来更新所有客户端的状态。
示例代码
const io = require('socket.io')(server);
let broadcast = {
audience: {}
};
function broadcastEvents(evt, args) {
// 将 args 转换为数组
args = args ? Array.prototype.slice.call(args) : [];
console.log(evt, args);
args.unshift(evt); // 在参数列表前添加事件名
console.log(args);
let audience = broadcast.audience;
for (let audId in audience) {
if (audience.hasOwnProperty(audId)) {
audience[audId].emit.apply(audience[audId], args);
}
}
}
io.on('connection', (socket) => {
console.log('A user connected:', socket.id);
socket.on('add-client', (clientId) => {
broadcast.audience[clientId] = socket;
console.log('Client added:', clientId);
});
socket.onEvent = function (evt, func) {
socket.on(evt, function () {
// 如果 func 返回 true,则广播该事件
if (func.apply(this, arguments)) {
broadcastEvents(evt, arguments);
}
});
};
socket.onEvent('draw-circle', function (x, y, color, width) {
canvas.drawing = {
type: 'circle',
color: color,
width: width,
points: [{ x: x, y: y }]
};
return true;
});
socket.on('disconnect', () => {
console.log('User disconnected:', socket.id);
delete broadcast.audience[socket.id];
});
});
const server = require('http').createServer();
server.listen(3000, () => {
console.log('Server listening on port 3000');
});
解释
-
初始化:
- 使用
socket.io
创建一个服务器实例。 - 定义
broadcast
对象用于存储连接的客户端。
- 使用
-
广播函数:
broadcastEvents
函数负责将事件和参数广播给所有客户端。它首先将参数转换为数组,并在参数列表前添加事件名,然后遍历broadcast.audience
并发送事件。
-
事件监听器:
- 当客户端连接时,将其添加到
broadcast.audience
中。 - 定义
socket.onEvent
方法,用于监听特定事件并调用回调函数。如果回调函数返回true
,则触发广播事件。
- 当客户端连接时,将其添加到
-
事件处理:
draw-circle
事件处理函数更新画布状态,并返回true
以触发广播。
-
断开连接:
- 当客户端断开连接时,从
broadcast.audience
中删除对应的客户端。
- 当客户端断开连接时,从
通过这种方式,可以确保在客户端连接、事件触发和广播时,操作能够按预期顺序执行,从而避免同步问题。
不好意思,还没有问问题就不小心给发布了。 我想问的是,上面的代码并没有emit(event,data)的形式,怎么就能实现响应绘图事件,并把事件数据广播至别的客户端的。还有就是apply真不懂,能给详细解释下吗? 谢谢了。