Object node.js在redis中存储对象

Object node.js在redis中存储对象,object,node.js,redis,Object,Node.js,Redis,我想在redis中的某个键下存储原生JS(node.JS)对象(flashsockets引用)。当我使用simpleclient.set()执行此操作时,它存储为字符串。当我尝试获取值时,我得到的是一个字符串 有机会让它工作吗?这是我的密码: addSocket : function(sid, socket) { client.set(sid, socket); }, getSocket : function(sid) { client.get(sid, funct

我想在redis中的某个键下存储原生JS(node.JS)对象(flashsockets引用)。当我使用simple
client.set()执行此操作时,它存储为字符串。当我尝试获取值时,我得到的是一个字符串

有机会让它工作吗?这是我的密码:

  addSocket : function(sid, socket) {
    client.set(sid, socket);
  },

  getSocket : function(sid) {
    client.get(sid, function(err, reply) {
      // cant't get an object here. All I get is useless string
    });
  },
向下投票者:这里的上下文是设置命令和存储任意对象的能力

不,你不能那样做。您应该接受这样一个事实:Redis将所有内容都存储为字符串(毕竟协议是基于文本的)。Redis可能会执行一些优化并将一些值转换为整数,但这是它的业务,不是你的

如果要在Redis中存储任意对象,请确保在保存前序列化它们,并在检索后反序列化它们


不过,我不确定你是否能用套接字对象做到这一点。它们只是简单地描述一个系统资源(一个开放的连接),毕竟(例如TCP套接字)。如果您设法序列化描述并在另一台计算机上反序列化它,则该另一台计算机将没有连接。

由于套接字的类型为
Object
,您需要在存储之前将对象转换为字符串,在检索套接字时,需要将其转换回对象

你可以用

JSON.stringify(socket) 
转换为字符串并

JSON.parse(socketstr) 
转换回一个对象

编辑:

自从版本
2.0.0
发布以来,我们能够将对象作为散列存储到Redis中

client.hmset("hosts", "mjr", "1", "another", "23", "home", "1234");

client.hgetall("hosts", function (err, obj) {
    console.dir(obj);
});


我相信,当您在存储对象之前在内部存储对象时,会调用
object.toString()
,这就是存储的值

({a: 1}).toString() # "[object Object]"
您需要做的是使用JSON.encode和JSON.parse

无法存储(隐藏的二进制)引用。

否则,您可能能够在整数和套接字之间建立对应关系,并存储整数

您可以使用如下技术保存对JavaScript对象的引用。基本上,它扩展了Object.prototype(不必),您可以调用radd()来添加对rhash{}的自定义引用,然后使用rget()检索对象。“reference”是一个字符串,因此它正好适合Redis。这意味着您不必使用.stringify()和.parse()在数据库中放置/获取副本。但是,当节点关闭时,对象的数据将被销毁,除非将其序列化

var OBJECT=OBJECT.prototype;
OBJECT.rhash={};
OBJECT.rset=函数(id,对象){
OBJECT.rhash[id]=对象;
返回id;
};
OBJECT.rget=函数(id){
返回OBJECT.rhash[id];
};
变量狗={
名字:“斯基皮”,
食物:“培根”,
树皮:功能(){
警报(this.name+“!”);
}
};
var id=OBJECT.rset(“a123”,dog);
var ref=OBJECT.rget(“a123”);
参考树皮();

下面的解决方案并没有解决使用redis的全部问题——跨集群实例共享数据。在redis中存储特定于实例的id对于另一个尝试使用该id的实例来说毫无意义

但是,有一个“hmset”可以用一个对象调用,它将每个对象字段设置为同一个键中的一个单独的redis字段。当您调用hgetall时,它将转换回一个对象。不幸的是,我认为它不处理对象中的嵌套对象或数组,只处理其值可由“toString()”存储的简单属性

那么像

client.hmset("myhashkey",{a:1, b:2, c:'xxx'})
非常有效,可以使用

client.hmget("myhashkey", function(obj) {
   console.log(obj);
});
对于以下方面,情况并非如此:

client.hmset("myhashkeynested",{a:1, b:2, c:'xxx', d: { d1: 'x', d2: 'y'}});

如果你想一想,javascript对象是键,谁的值可以引用其他对象,在套接字的情况下可能是本地对象。因此,如果redis位于正在执行的javascript外部,它将如何存储对该对象的引用

// a and b exist inside the executing javascript, not in the external O/S
a = {}
b = {}

var obj = {
  'one': a,
  'two': b
}

// how can redis possibly store references to obj, a or b when this application exits?
redis.set('obj', obj)

// same as..
redis.set('obj', obj.toString()) /*or*/ redis.set('obj', "" + obj)

// same as..
redis.set('obj', "[object Object]")


// the trick is to stringify the object
redis.set('obj', JSON.stringify(obj))

// same as..
redis.set('obj', "{'one':{},'two':{}}")

// here redis does not have to store the actual object references but rather a json string representing the object

// this could also work
redis.set('obj', "{'one':a,'two':b}")

// where you would then do:
obj = eval(redis.get('obj')) 
// provided that a and b have already been initialized

我还发现这是一个非常有用的工具,特别是当您将JSON从API引导到前端时:


如果您接收到一大块JSON,并且无法将其存储为特定的哈希,那么在存储时对其进行字符串化将允许您检索整个JSON,而不仅仅是“[object]”.

您不能将对javascript的引用存储在某种形式的数据库中,因为当服务器关闭时对象会消失。不要修改
对象。原型
!为什么需要将其绑定到Object.prototype并生成这些get/set方法,而不是只执行hash={},hash[key]=Object?另外,这里没有发生序列化。引用是指向原始对象,而不是字符串。检索人:
client.hgetall(“键名”,函数(err,obj){/…})
,用于
hmget
need
字段名
。这个答案需要更多的投票!接受的答案为false。@JMTyler:这对存储任意js对象(本例中为套接字)没有帮助。这是专门用于存储js对象的。它将成功地存储套接字对象的任何和所有基元类型顶级属性,因为JS中的每个对象都扩展了基本对象。最糟糕的情况是,如果套接字对象是嵌套的,请将其转换为未嵌套的表单,您仍然可以通过这种方式将其保存为对象。遗憾的是,
a
b
在使用
hgetall
时将以字符串形式返回,这使得此操作更加棘手。这就是答案!你不能做的事情永远都不是答案。tnx Shawn,但它能和插座一起工作吗?你能在另一台机器(甚至是同一台机器)上反序列化一个套接字并开始,比如说,将数据推入其中吗?@moeiscool有很多答案,因此应该是可接受的答案,但问题操作并不总是关心它,他们也不会改变可接受的答案。应该有版主权限更改已接受的答案。关于编辑,您可以在哈希中存储多个键值对,但每个键值仍然是字符串。因此,包含非字符串值的任意JS对象仍然无法按原样存储,因此将其字符串化为JSON可能仍然是更好的选择