ich mit Redigo Redis Bibliothek arbeite und das Ergebnis zu json.Marshal ich versucht, aus einer sortierten Reihe bekommen, aber ich Ergebnisse zu erhalten wie folgt aus:seltsame Ergebnisse zu erzielen, wenn JSON Rangier Nahtstellenbyte Scheiben
"eyJmcm9tSWQiOjEsInRvSWQiOjUsInR5cGUiOjMsInBvc3RJZCI6MSwiY29tbWVudElkIjo0NCwiY3JlYXRlZFRpbWUiOjE0NjMxNTY0ODQsImlzVmlld2VkIjpmYWxzZSwidXNlcm5hbWUiOiJBZG1pbiIsImltYWdlIjoiaHc2ZE5EQlQtMzZ4MzYuanBnIn0="
Als ich sollte immer dies:
"{"fromId":5,"toId":1,"type":3,"postId":4,"commentId":49,"createdTime":1463161736,"isViewed":false,"username":"Alexander","image":"JZIfHp8i-36x36.png"}"
ich habe eine Benachrichtigung struct
type Notification struct {
FromId int64 `json:"fromId"`
ToId int64 `json:"toId"`
OfType int64 `json:"type"`
PostId int64 `json:"postId"`
CommentId int64 `json:"commentId"`
CreatedTime int64 `json:"createdTime"`
IsViewed bool `json:"isViewed"`
FromUsername string `json:"username"`
FromImage string `json:"image"`
}
func New() *Notification {
return &Notification{
CreatedTime: time.Now().Unix(),
}
}
Es verfügt über eine Methode, die eine Zeichenkette von json in eine nach Redis sortierte Menge speichert.
func (n *Notification) Create(pool *redis.Pool, multicast chan<- []byte) error {
var err error
n.FromUsername, err = validation.FilterUsername(n.FromUsername)
if err != nil {
return err
}
// We can use the same validation as for a username here.
n.FromImage, err = validation.FilterUsername(n.FromImage)
if err != nil {
return err
}
key := fmt.Sprintf("user:%d:notification", n.ToId)
b, err := json.Marshal(n)
if err != nil {
return err
}
c := pool.Get()
defer c.Close()
c.Send("ZADD", key, n.CreatedTime, string(b))
// Limiting to the top ranked 50 items.
c.Send("ZREMRANGEBYRANK", key, 0, -50)
if err := c.Flush(); err != nil {
return err
}
multicast <- b
return nil
}
Das funktioniert alles gut. Aber dann möchte ich diese Ergebnisse abrufen und dann als ein Array von json-formatierten Strings an die Client-Seite senden. Dieselben JSON-formatierten Strings, die ich im sortierten Set speichere.
Ich mache etwas einfach so.
func ByUserId(userId int64, pool *redis.Pool) (interface{}, error) {
key := fmt.Sprintf("user:%d:notification", userId)
c := pool.Get()
defer c.Close()
c.Send("ZREVRANGE", key, 0, -1)
c.Flush()
return c.Receive()
}
Aber es funktioniert nicht.
Wenn ich das Ergebnis json.Marshal bekomme ich ein Array von Strings wie folgt aus:
"eyJmcm9tSWQiOjEsInRvSWQiOjUsInR5cGUiOjMsInBvc3RJZCI6MSwiY29tbWVudElkIjo0NCwiY3JlYXRlZFRpbWUiOjE0NjMxNTY0ODQsImlzVmlld2VkIjpmYWxzZSwidXNlcm5hbWUiOiJBZG1pbiIsImltYWdlIjoiaHc2ZE5EQlQtMzZ4MzYuanBnIn0="
Wenn ich spew.Dump() die Ergebnisse ich diese Ausgabe erhalten:
([]interface {}) (len=1 cap=1) {
([]uint8) (len=149 cap=149) {
00000000 7b 22 66 72 6f 6d 49 64 22 3a 35 2c 22 74 6f 49 |{"fromId":5,"toI|
00000010 64 22 3a 31 2c 22 74 79 70 65 22 3a 33 2c 22 70 |d":1,"type":3,"p|
00000020 6f 73 74 49 64 22 3a 34 2c 22 63 6f 6d 6d 65 6e |ostId":4,"commen|
00000030 74 49 64 22 3a 34 39 2c 22 63 72 65 61 74 65 64 |tId":49,"created|
00000040 54 69 6d 65 22 3a 31 34 36 33 31 36 31 37 33 36 |Time":1463161736|
00000050 2c 22 69 73 56 69 65 77 65 64 22 3a 66 61 6c 73 |,"isViewed":fals|
00000060 65 2c 22 75 73 65 72 6e 61 6d 65 22 3a 22 53 74 |e,"username":"Al|
00000070 61 72 64 75 73 6b 22 2c 22 69 6d 61 67 65 22 3a |exander","image":|
00000080 22 4a 5a 49 66 48 70 38 69 2d 33 36 78 33 36 2e |"JZIfHp8i-36x36.|
00000090 70 6e 67 22 7d |png"}|
}
}
Was kann Ich mache?
EDIT:
Dies ist, was ich am Ende tat, aber es fühlt sich an wie eine Menge unnötiger Umwandlung.
func ByUserId(userId int64, pool *redis.Pool) ([]string, error) {
key := fmt.Sprintf("user:%d:notification", userId)
c := pool.Get()
defer c.Close()
c.Send("ZREVRANGE", key, 0, -1)
c.Flush()
reply, err := c.Receive()
if err != nil {
return nil, nil
}
arr, ok := reply.([]interface{})
if !ok {
return nil, err
}
ss := []string{}
for _, v := range arr {
b, ok := v.([]byte)
if !ok {
return nil, nil
}
ss = append(ss, string(b))
}
return ss, nil
}
Und auf dem Griff:
func notifications(w http.ResponseWriter, r *http.Request, _ httprouter.Params) error {
userId, err := user.LoggedIn(r)
if err != nil {
return unauthorized
}
jsonResp := make(map[string]interface{})
jsonResp["notifications"], err = notification.ByUserId(userId, redisPool)
if err != nil {
return err
}
jsonResp["success"] = true
b, err := json.Marshal(jsonResp)
if err != nil {
return err
}
w.Write(b)
return nil
}
ich nicht von ihnen verwenden. Wie würde ich sie in diesem Fall verwenden? – Alex
Sie ordnen die von redis zurückgegebenen unverarbeiteten Bytes zu. Sie müssen nicht marshalen, was bereits json ist. – JimB
Wie kann ich dann ein Array dieser JSON-Strings in der Antwort ausgeben? Ich kann nicht umhin zu denken, dass ich diese Schnittstellentypen konvertieren und ein paar Schleifen machen muss. – Alex