Socket.io 如何设置不同的房间权限

前言

Socket.io 是一种实时网络通信协议,常用于开发实时通信应用,如聊天室、多人游戏等。在构建这样的应用时,我们需要为不同房间设置不同的权限,以便控制用户的访问权限。

本文将介绍如何使用 Socket.io 来设置不同的房间权限,并提供示例代码。

Socket.io 的房间权限

在使用 Socket.io 时,我们可以使用房间(Room)来组织客户端。房间是 Socket.io 命名空间(Namespace)的子集,可以用来分组客户端。

在 Socket.io 中,每个客户端都可以加入一个或多个房间,并通过 socket.join(room) 方法来加入一个指定房间(如果该房间不存在,则创建该房间)。我们还可以使用 socket.leave(room) 方法来离开一个指定房间。

当向房间发送消息时,只有加入该房间的客户端才会接收到这条消息。

// 将客户端加入一个名为房间1的房间
socket.join('房间1');
// 向房间1发送一条消息
io.to('房间1').emit('message', 'Hello, World!');

在 Socket.io 中,房间是公共的,任何客户端都可以加入或离开房间。因此,我们需要一种方法来控制客户端的访问权限,以便只有特定的客户端才能访问某些房间。

一个常见的应用场景是聊天室,在聊天室中,只有被授权的用户才能加入某些房间。

如何设置房间权限

要设置 Socket.io 房间的权限,我们需要在客户端连接服务器时对客户端进行身份验证,然后在客户端加入房间之前对其进行授权。

以下是一个简单的身份验证流程示例:

// 服务器端,身份验证
io.use((socket, next) => {
  // 获取客户端的请求中的 token
  const token = socket.handshake.query.token;
  // 验证 token 是否有效
  if (isValidToken(token)) {
    // 将客户端信息加入 Auth 客户端中
    AuthClient.add(socket.id, token);
    // 身份验证通过,继续处理
    next();
  } else {
    // 身份验证失败,终止连接
    next(new Error('Authentication error'));
  }
});

在客户端加入房间之前,我们需要通过服务器的身份验证来检查客户端是否被授权加入指定的房间。

下面是一个简单的房间授权流程:

// 客户端加入房间前,进行房间授权
socket.on('join room', (roomId) => {
  // 获取客户端信息
  const client = AuthClient.get(socket.id);
  if (client) {
    // 获取客户端的角色信息
    const role = UserRole.get(client.userId);
    // 检查角色是否有权限加入该房间
    if (role && role.canAccess(roomId)) {
      // 授权通过,让客户端加入房间
      socket.join(roomId);
      // 加入房间成功,通知客户端
      socket.emit('join room success', roomId);
    } else {
      // 授权失败,通知客户端
      socket.emit('join room fail', roomId);
    }
  } else {
    // 客户端信息不存在,拒绝加入房间
    socket.emit('join room fail', roomId);
  }
});

在上面的示例中,UserRole 是一个表示用户角色的类,它有一个名为 canAccess 的方法,用于检查用户是否有权限访问指定房间。

示例代码

下面是一个完整的应用程序示例,用于演示如何设置 Socket.io 房间权限。该示例应用程序使用身份验证来验证客户机的身份,并使用角色权限来控制客户机对特定房间的访问权限。

服务器端代码

const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
const { AuthClient, UserRole } = require('./auth');

// 身份验证
io.use((socket, next) => {
  // 获取客户端的请求中的 token
  const token = socket.handshake.query.token;
  // 验证 token 是否有效
  if (isValidToken(token)) {
    // 将客户端信息加入 Auth 客户端中
    AuthClient.add(socket.id, token);
    // 身份验证通过,继续处理
    next();
  } else {
    // 身份验证失败,终止连接
    next(new Error('Authentication error'));
  }
});

// 房间授权
io.on('connection', (socket) => {
  // 加入房间
  socket.on('join room', (roomId) => {
    // 获取客户端信息
    const client = AuthClient.get(socket.id);
    if (client) {
      // 获取客户端的角色信息
      const role = UserRole.get(client.userId);
      // 检查角色是否有权限加入该房间
      if (role && role.canAccess(roomId)) {
        // 授权通过,让客户端加入房间
        socket.join(roomId);
        // 加入房间成功,通知客户端
        socket.emit('join room success', roomId);
      } else {
        // 授权失败,通知客户端
        socket.emit('join room fail', roomId);
      }
    } else {
      // 客户端信息不存在,拒绝加入房间
      socket.emit('join room fail', roomId);
    }
  });

  // 离开房间
  socket.on('leave room', (roomId) => {
    socket.leave(roomId);
  });

  // 接收房间消息
  socket.on('room message', (roomId, message) => {
    // 检查客户端是否在指定的房间中
    if (socket.rooms.has(roomId)) {
      // 检查客户端是否有权限发送消息
      const client = AuthClient.get(socket.id);
      const role = UserRole.get(client.userId);
      if (role && role.canSend(roomId)) {
        // 客户端有权限发送消息,发送给房间中的所有客户端
        io.to(roomId).emit('room message', message);
      }
    }
  });
});

// 启动服务器监听
server.listen(3000, () => {
  console.log('Server listening on port 3000');
});

客户端代码

const socket = io('http://localhost:3000', {
  query: {
    token: 'xxxxx',  // 这里填写你的实际 token
  },
});

// 加入房间
socket.emit('join room', 'room1');
socket.on('join room success', (roomId) => {
  console.log(`成功加入房间 ${roomId}`);
});
socket.on('join room fail', (roomId) => {
  console.log(`加入房间 ${roomId} 失败`);
});

// 离开房间
socket.emit('leave room', 'room1');

// 发送房间消息
socket.emit('room message', 'room1', 'Hello, World!');
socket.on('room message', (message) => {
  console.log(`收到房间消息:${message}`);
});

总结

本文介绍了 Socket.io 如何设置不同房间的权限。通过身份验证和角色授权,我们可以有效地控制客户端对特定房间的访问权限。我们还提供了一个完整的示例,演示了如何在 Node.js 中实现一个带有房间权限的聊天室应用程序。

希望本文能给你带来帮助。如果你有任何疑问或建议,请在评论区留言。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/659e4a91add4f0e0ff74ce6f


纠错反馈