Nodejs addon redis 模块 简单的命令出现乱码

Nodejs addon redis 模块 简单的命令出现乱码

通过各种努力和网络上的高手帮助,终于可以使用CPP构建出一个redis的addon,并且可以正常运行不报错,但是简单的一个PING命令出现了乱码(官方的example.c不会出现乱码),正确返回是PONG,但是我返回了p�T ,并且每运行一次p是保持不变的,后面的几个字符会出现各种变化(但都不是可读的英文),另外我更改了命令使用llen(获取list的长度),正确应该是返回一串数字,但是直接出错退出了。

请问各位遇到过这样的情况吗?

4 回复

针对您提到的Node.js Redis模块在执行命令时出现乱码的问题,这通常是由于字符编码不匹配或者数据类型处理不当所导致。为了帮助您解决这个问题,我们将通过一个简单的示例来说明如何正确地处理字符串数据。

首先,确保您已经安装了正确的Redis C库和对应的Node.js绑定库。假设我们使用的是node-redis库,这是一个广泛使用的Node.js Redis客户端。

示例代码

1. 安装依赖

npm install redis

2. 创建一个简单的Node.js脚本

const redis = require('redis');

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

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

// 使用PING命令测试连接
client.ping((err, res) => {
    if (err) {
        console.error(err);
    } else {
        console.log(`Pong: ${res}`); // 正确输出应为 "Pong: PONG"
    }
});

// 获取列表长度
client.llen('myList', (err, res) => {
    if (err) {
        console.error(err);
    } else {
        console.log(`Length of myList: ${res}`); // 应该是一个数字
    }
});

常见问题及解决方案

  1. 字符编码问题:

    • 确保您的Redis服务器配置正确,没有设置非标准的编码。
    • 在Node.js中处理字符串时,确保使用正确的编码(如UTF-8)。
  2. 数据类型错误:

    • 当使用llen等命令时,确保Redis中存储的数据类型与预期一致。例如,如果myList不是一个列表,llen命令将失败。
  3. Redis版本兼容性:

    • 确保您使用的node-redis版本与Redis服务器版本兼容。

调试建议

  • 在执行命令前,检查Redis中的数据是否正确。
  • 使用Redis CLI工具直接测试命令,确保它们按预期工作。
  • 如果问题仍然存在,尝试更新或降级node-redis库版本。

希望这些信息能帮助您解决问题!如果还有其他疑问,请随时提问。


为什么要自己写addon呢?node-redis很好用啊,而且也是官方推荐的redis客户端

https://github.com/mranney/node_redis

目前这个有什么满足不了你的了???

支持纯js 和 hiredis 两种模式…

根据你的描述,这个问题可能是由于字符编码或字符串处理不当导致的。在Node.js的C++扩展中,确保字符串正确地从Redis读取并传递回JavaScript环境非常重要。

以下是一些可能的解决方案和建议:

  1. 确保使用正确的编码:当从Redis读取字符串时,确保它以正确的格式返回。通常情况下,Redis返回的数据应该是UTF-8编码的字符串。

  2. 检查数据类型转换:确保你在C++代码中正确地将数据类型从C++的std::string转换为JavaScript的字符串。

  3. 错误处理:确保你的代码能够正确处理任何可能发生的错误,比如Redis连接问题或数据格式问题。

下面是一个简单的示例代码,展示如何正确地从Redis执行命令并返回结果:

#include <node.h>
#include <node_buffer.h>
#include <uv.h>
#include <cstring>

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;

extern "C" {
    #include <hiredis/hiredis.h>
}

void PING(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();

    // 创建Redis上下文
    redisContext *c = redisConnect("127.0.0.1", 6379);
    if (c == NULL || c->err) {
        if (c) {
            fprintf(stderr, "Connection error: %s\n", c->errstr);
            redisFree(c);
        } else {
            fprintf(stderr, "Connection error: can't allocate redis context\n");
        }
        return;
    }

    // 执行PING命令
    redisReply *reply = (redisReply *)redisCommand(c, "PING");

    if (reply == NULL) {
        fprintf(stderr, "Error: %s\n", c->errstr);
        redisFree(c);
        return;
    }

    // 检查回复是否成功
    if (reply->type == REDIS_REPLY_ERROR) {
        fprintf(stderr, "Error: %s\n", reply->str);
        freeReplyObject(reply);
        redisFree(c);
        return;
    }

    // 将结果转换为V8字符串
    Local<String> result = String::NewFromUtf8(isolate, reply->str).ToLocalChecked();
    args.GetReturnValue().Set(result);

    // 清理资源
    freeReplyObject(reply);
    redisFree(c);
}

void Initialize(Local<Object> exports) {
    NODE_SET_METHOD(exports, "ping", PING);
}

NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)

在这个示例中,我们使用redisCommand函数执行Redis命令,并将结果转换为UTF-8编码的V8字符串。这应该能解决乱码问题。如果仍然有问题,请检查Redis服务器的日志文件以获得更多信息。

回到顶部