Nodejs 和 redis 以及 socket.io 搭建的聊天室,突然出了问题,大家帮我看看

Nodejs 和 redis 以及 socket.io 搭建的聊天室,突然出了问题,大家帮我看看

问题已经解决。是redis 的 zadd 方法导致的。

msg_sender.zadd(socket.online_list, socket.level, socket.json_info); socket.level的值是从页面获取的到,当没传level时,socket.level变成了undefined。所有就报错了。 我也亲自在redis 客户端也试过了: redis 192.168.13.109:6380> zadd test undefined 33 (error) ERR value is not a valid float redis 192.168.13.109:6380>

谢谢。


2 回复

根据你提供的帖子内容,问题出在 zadd 方法的使用上。Redis 的有序集合(Sorted Set)操作 zadd 需要传入一个浮点数值作为分数(score),而不能是一个 undefined 值。如果 socket.levelundefined,那么调用 zadd 就会抛出错误。

示例代码及解释

假设你的 Node.js 应用使用了 Redis 和 Socket.IO 来实现一个简单的聊天室。以下是简化后的代码示例:

安装依赖

首先确保安装了必要的库:

npm install redis socket.io

Node.js 服务端代码

const redis = require('redis');
const io = require('socket.io')(3000);

// 创建 Redis 客户端
const client = redis.createClient({
    host: '192.168.13.109',
    port: 6380
});

client.on('error', (err) => {
    console.error(`Redis error: ${err}`);
});

io.on('connection', (socket) => {
    console.log('A user connected');

    // 接收来自客户端的消息
    socket.on('send:message', (data) => {
        const { level, message } = data;

        if (typeof level === 'undefined') {
            console.error('Level is undefined');
            return;
        }

        // 使用 level 作为 score 添加到有序集合中
        client.zadd(socket.online_list, level, message, (err, response) => {
            if (err) {
                console.error(`Redis error: ${err}`);
            } else {
                console.log(`Message added with score ${level}`);
            }
        });

        // 广播消息给所有连接的客户端
        socket.broadcast.emit('receive:message', message);
    });

    socket.on('disconnect', () => {
        console.log('User disconnected');
    });
});

解释

  • Redis 客户端创建:我们创建了一个 Redis 客户端,并监听 Redis 错误事件。
  • Socket.IO 连接处理:当有新用户连接时,我们打印一条日志。
  • 消息发送处理:当收到消息时,我们检查 level 是否为 undefined。如果是,则打印错误信息并退出函数。
  • 使用 zadd 方法:如果 level 不是 undefined,则使用 zadd 方法将消息添加到有序集合中。如果发生错误,我们将打印错误信息。
  • 广播消息:最后,我们使用 socket.broadcast.emit 方法将消息广播给所有连接的客户端。

通过这种方式,我们可以确保不会向 Redis 发送无效的数据,从而避免出现 ERR value is not a valid float 错误。


根据你的描述,问题出在 zadd 方法中传递了一个 undefined 值作为分数参数。Redis 的有序集合(Sorted Set)要求分数必须是浮点数,因此 undefined 导致了错误。

示例代码

修正后的代码

const redis = require('redis');
const socketIo = require('socket.io');

// 创建 Redis 客户端
const client = redis.createClient({
    host: '192.168.13.109',
    port: 6380
});

client.on('error', (err) => {
    console.error(`Redis error: ${err}`);
});

const io = socketIo(server);

io.on('connection', (socket) => {
    socket.on('login', (data) => {
        const { level } = data;

        // 确保 level 不是 undefined
        if (typeof level === 'undefined') {
            console.error('Level is undefined');
            return;
        }

        // 添加到有序集合
        client.zadd(socket.online_list, level, socket.json_info, (err, response) => {
            if (err) {
                console.error(`Redis error: ${err}`);
                return;
            }
            console.log(`Added to set: ${response}`);
        });
    });

    socket.on('disconnect', () => {
        // 处理断开连接逻辑
    });
});

解释

  1. 确保 level 不是 undefined:在调用 zadd 方法之前,检查 level 是否为 undefined。如果 levelundefined,则不执行 zadd 操作并输出错误信息。

  2. Redis 错误处理:在 Redis 客户端上添加错误处理,以捕获和显示任何潜在的 Redis 错误。

通过这些修改,可以避免因传递 undefined 作为浮点数而导致的 Redis 错误。

回到顶部