web-dev-qa-db-fra.com

node.js stocke les objets dans redis

Voici la chose - je veux stocker des objets JS natifs (node.js) (références de sockets flash) dans redis sous une certaine clé. Quand je fais ça avec une simple client.set() elle est stockée sous forme de chaîne. Lorsque j'essaie d'obtenir de la valeur, j'obtiens [object Object] - juste une chaîne.

Une chance de faire fonctionner ça? 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
    });
  },
45
Pono

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

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

Si vous souhaitez stocker des objets arbitraires dans Redis, assurez-vous de les sérialiser avant d'enregistrer et de désérialiser après la récupération.

Je ne sais pas si vous pouvez le faire avec des objets socket, cependant. Ils décrivent simplement une ressource système (une connexion ouverte), après tout (sockets TCP, par exemple). Si vous parvenez à sérialiser la description et à la désérialiser sur une autre machine, cette autre machine n'aura pas la connexion.

33
Sergio Tulentsev

Étant donné que le socket est de type Object, vous devez convertir l'objet en chaîne avant de le stocker et lors de la récupération du socket, vous devez le reconvertir en objet.

Vous pouvez utiliser

JSON.stringify(socket) 

pour convertir en chaîne et

JSON.parse(socketstr) 

pour reconvertir en objet.

Modifier:

Depuis la sortie de la version 2.0.0, nous pouvons stocker des objets sous forme de hachages 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

117
Shawn Janas

La solution ci-dessous ne résout pas tout l'intérêt d'utiliser redis - pour partager des données entre les instances de cluster. Le stockage d'un identifiant spécifique à l'instance dans redis n'aura aucun sens pour une autre instance qui essaie d'utiliser cet identifiant.

Cependant, il existe "hmset" qui peut être appelé avec un objet et il définira chaque champ d'objet comme un champ redis distinct dans la même clé. Et il sera reconverti en objet lorsque vous appelez 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 ()".

Donc 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 pour:

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

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

node-redis-jsonify

Si vous recevez un énorme bloc de JSON et ne pouvez pas le stocker en tant que hachage spécifique, le filtrer pendant le stockage vous permettra de récupérer l'intégralité du json au lieu de simplement "[object object]".

6
Zoombear

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

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

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

Vous ne pouvez pas stocker de références (masquées, binaires).
Sinon, vous pourrez peut-être établir une correspondance entre des entiers et des sockets et stocker des entiers.

3
clyfe