node.js store objects in redis

2019-03-11 14:40发布

Here is the thing - I want to store native JS (node.js) objects (flash sockets references) in redis under a certain key. When I do that with simple client.set() it's stored as a string. When I try to get value I get [object Object] - just a string.

Any chance to get this working? Here's my code:

  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
    });
  },

7条回答
欢心
2楼-- · 2019-03-11 14:54

I belive that when you store the object, internally, before storage object.toString() is called and that is the value that is stored.

({a: 1}).toString() # "[object Object]"

What you need to do is use JSON.encode and JSON.parse.

You cannot store (hidden, binary) references.
Otherwise, you might be able to make a correspondence between integers and sockets, and store integers.

查看更多
冷血范
3楼-- · 2019-03-11 14:54

You can save a reference to the JavaScript object, using a technique like this. Basically, it extends Object.prototype (doesn't have to) and you can call radd() to add a custom reference to rhash{}, then retrieve the object with rget(). The "reference" is a string so it will fit right into Redis. This means you won't have to .stringify() and .parse() to put/get a copy in the database. However, the object's data will be destroyed when Node shuts down unless its serialized.

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();
查看更多
男人必须洒脱
4楼-- · 2019-03-11 14:56

Since the socket is of type Object, you need to convert the object to a string before storing and when retrieving the socket, need to convert it back to an object.

You can use

JSON.stringify(socket) 

to convert to a string and

JSON.parse(socketstr) 

to convert back to an object.

查看更多
一夜七次
5楼-- · 2019-03-11 14:59

The solution below doesn't solve the whole point of using redis -- to share data across cluster instances. Storing an instance-specific id in redis will be meaningless to another instance that tries to use that id.

However, there is "hmset" which can be called with an object and it will set each object field as a separate redis field in the same key. And it will be converted back to an object when you call hgetall. Unfortunately, I don't think it handles nested objects or arrays within an object, only simple properties whose values can be stored by "toString()".

So an object like

client.hmset("myhashkey",{a:1, b:2, c:'xxx'})

works great and can be retrieved with

client.hmget("myhashkey", function(obj) {
   console.log(obj);
});

Not so much for:

client.hmset("myhashkeynested",{a:1, b:2, c:'xxx', d: { d1: 'x', d2: 'y'}});
查看更多
虎瘦雄心在
6楼-- · 2019-03-11 15:04

Downvoters: the context here is SET command and ability to store arbitrary objects.

No, you can't do that. You should accept the fact that Redis stores everything as a string (the protocol is text-based, after all). Redis may perform some optimizations and convert some values to integers, but that's its business, not yours.

If you want to store arbitrary objects in Redis, make sure that you serialize them before saving and de-serialize after retrieving.

I'm not sure if you can do that with socket objects, though. They simply describe a system resource (an open connection), after all (TCP sockets, for example). If you manage to serialize the description and deserialize it on another machine, that other machine won't have the connection.

查看更多
Rolldiameter
7楼-- · 2019-03-11 15:10

I also found this to be an incredibly useful tool, especially if you are channeling JSON from an API to your front-end:

node-redis-jsonify

If you're receiving a huge block of JSON and can't store as a specific hash, stringifying it while storing will allow you to retrieve the whole json instead of just "[object Object]".

查看更多
登录 后发表回答