这是事情 - 我希望在某个密钥下的redis中存储本机JS(node.js)对象(闪存套接字引用)。当我使用简单client.set()
执行此操作时,它将存储为字符串。当我试图获得价值时,我得到[object Object]
- 只是一个字符串。
有机会让这个工作吗?这是我的代码:
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
});
},
答案 0 :(得分:112)
由于套接字的类型为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);
});
答案 1 :(得分:30)
Downvoters:这里的上下文是SET命令和存储任意对象的能力。
不,你不能这样做。您应该接受Redis将所有内容存储为字符串的事实(该协议毕竟是基于文本的)。 Redis可以执行一些优化并将一些值转换为整数,但这是它的业务,而不是你的业务。
如果要在Redis中存储任意对象,请确保在检索之后对其进行序列化,然后再进行保存和反序列化。
但是,我不确定你是否可以使用套接字对象。毕竟它们只是描述了一个系统资源(一个开放的连接)(例如TCP套接字)。如果您设法序列化描述并在另一台机器上反序列化,则该另一台机器将没有连接。答案 2 :(得分:30)
以下解决方案无法解决使用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'}});
答案 3 :(得分:6)
我还发现这是一个非常有用的工具,特别是如果你将JSON从API引导到你的前端:
如果您正在接收大量JSON并且无法存储为特定哈希,则在存储时对其进行字符串化将允许您检索整个json而不仅仅是" [object Object] "
答案 4 :(得分:3)
我相信当你在调用存储object.toString()
之前在内部存储对象时,这就是存储的值。
({a: 1}).toString() # "[object Object]"
您需要做的是使用JSON.encode和JSON.parse。
您无法存储(隐藏的,二进制)参考文献 否则,您可能能够在整数和套接字之间建立对应关系,并存储整数。
答案 5 :(得分:-2)
您可以使用这样的技术保存对JavaScript对象的引用。基本上,它扩展了Object.prototype(不必),你可以调用radd()来为rhash {}添加自定义引用,然后用rget()检索对象。 “引用”是一个字符串,因此它适合Redis。这意味着您不必使用.stringify()和.parse()来在数据库中放置/获取副本。但是,当节点关闭时,对象的数据将被销毁,除非它被序列化。
var OBJECT = Object.prototype;
OBJECT.rhash = {};
OBJECT.rset = function(id, object) {
OBJECT.rhash[id] = object;
return id;
};
OBJECT.rget = function(id) {
return OBJECT.rhash[id];
};
var dog = {
name: "Skippy",
food: "Bacon",
bark: function() {
alert(this.name + "!");
}
};
var id = OBJECT.rset("a123", dog);
var ref = OBJECT.rget("a123");
ref.bark();
答案 6 :(得分:-2)
好吧,如果你考虑一下,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