72 votes

node.js stocker des objets dans redis

Voici le problème : je veux stocker des objets JS natifs (node.js) (références flash sockets) dans redis sous une certaine clé. Lorsque je fais cela avec de simples client.set() il est stocké sous forme de chaîne. Lorsque j'essaie de récupérer la valeur, j'obtiens [object Object] - juste une chaîne.

Y a-t-il une chance que cela fonctionne ? Voici mon 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
    });
  },

0 votes

Vous ne pouvez pas stocker les références à javascript dans une forme de base de données parce que les objets disparaissent lorsque le serveur tombe en panne

159voto

Shawn Janas Points 534

Puisque la prise est de type Object Dans ce cas, vous devez convertir l'objet en chaîne de caractères avant de le stocker et, lorsque vous récupérez le socket, vous devez le reconvertir en objet.

Vous pouvez utiliser

JSON.stringify(socket) 

pour convertir en chaîne de caractères et

JSON.parse(socketstr) 

pour le reconvertir en objet.

Edit :

Depuis la sortie de la version 2.0.0 nous sommes en mesure de stocker des objets sous forme de hachage dans Redis.

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

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

https://redis.io/commands/hset

https://github.com/NodeRedis/node_redis

61voto

Sergio Tulentsev Points 82783

Downvoters : le contexte ici est la commande SET et la capacité de stocker des objets arbitraires.

Non, vous ne pouvez pas faire ça. Vous devez accepter le fait que Redis stocke tout sous forme de chaîne de caractères (le protocole est basé sur le texte, après tout). Redis peut effectuer quelques optimisations et convertir certaines valeurs en entiers, mais c'est son affaire, pas la vôtre.

Si vous voulez stocker arbitraire dans Redis, assurez-vous de les sérialiser avant de les sauvegarder et de les dé-sérialiser après les avoir récupérés.

Je ne suis pas sûr que l'on puisse faire cela avec des objets socket, cependant. Ils décrivent simplement une ressource système (une connexion ouverte), après tout (les sockets TCP, par exemple). Si vous parvenez à sérialiser la description et à la désérialiser sur une autre machine, cette autre machine ne disposera pas de la connexion.

49voto

Jason Loveman Points 597

La solution ci-dessous ne résout pas le problème de l'utilisation de redis - le partage des données entre les instances du cluster. Stocker un identifiant spécifique à une instance dans redis n'aura aucun sens pour une autre instance qui essaiera d'utiliser cet identifiant.

Cependant, il y a "hmset" qui peut être appelé avec un objet et qui va définir chaque champ de l'objet comme un champ redis séparé dans la même clé. Et il sera reconverti en objet lorsque vous appellerez hgetall. Malheureusement, je ne pense pas qu'il gère les objets imbriqués ou les tableaux dans un objet, seulement les propriétés simples dont les valeurs peuvent être stockées par "toString()".

Ainsi, un objet comme

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

fonctionne très bien et peut être récupéré avec

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

Pas tant que ça :

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

7voto

Zoombear Points 93

J'ai également trouvé que c'était un outil incroyablement utile, surtout si vous canalisez le JSON d'une API vers votre front-end :

node-redis-jsonify

Si vous recevez un énorme bloc de JSON et que vous ne pouvez pas le stocker sous la forme d'un hachage spécifique, le fait d'utiliser une chaîne de caractères lors du stockage vous permettra de récupérer l'intégralité du JSON au lieu de simplement "[objet Objet]".

1 votes

Ce paquet est un moyen long et fastidieux de faire simplement JSON.stringify et JSON.parse. Consultez la source.

3voto

clyfe Points 15388

Je pense que lorsque vous stockez l'objet, en interne, avant le stockage object.toString() est appelé et c'est la valeur qui est stockée.

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

Ce que vous devez faire, c'est utiliser JSON.encode et JSON.parse.

Vous ne pouvez pas stocker des références (cachées, binaires).
Sinon, vous pourriez établir une correspondance entre les entiers et les sockets, et stocker des entiers.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X