2016-12-17 2 views
1

Ich benutze Gin-Framework, um einen API-Server zu erstellen. Im Allgemeinen baue ich 2 Projekte. Projekt und Projekt 'SOCKET'. Das Projekt 'API' ist die wichtigste REST-API, die in Android verwendet wird und mit gin Framework (Golang) entwickelt wurde. Und Projekt 'SOCKET' ist der Socket-Server für Client, der Socket-Verbindung verwenden, mit node.js (Socket.IO)Wie sicherzustellen, Redis Teilnehmer empfangen Nachricht in Go (Golang)?

Der Prozess beginnt wie folgt aus:
Benutzer A: als Anforderer; Eine Verbindung zu "API"
Benutzer B: als Responder; B Verbindung zu "SOCKET"

User A Aufruf API requestData von Android, die Anfrage von "API" ‚s Projekt behandelt wird. Und Projekt "API" wird die Anfrage aufnehmen und veröffentlicht auf redis als new_request mit PubSub

dies der Code zum Beispiel:

client := redis.NewClient(&redis.Options{ 
    Addr:  "localhost:6379", 
    Password: "", // no password set 
    DB:  0, // use default DB 
}) 

pong, err := client.Ping().Result() 

fmt.Println(pong, err) 

if err !=nil { 
    fmt.Println("err",err); 
} 


pubsub, err := client.Subscribe("responseclient") 
if err !=nil { 
    panic(err) 
} 
defer pubsub.Close() 

err = client.Publish("new_request", "Example New Request").Err() 

if err !=nil { 
    panic(err) 
} 
msg, err :=pubsub.ReceiveMessage() 
if err != nil { 
    panic(err) 
} 

fmt.Println(msg.Channel, msg.Payload) 

}

Im Projekt "SOCKET" gibt es einen Teilnehmer, der zuhört Jede Veröffentlichung, die aufgetreten ist, und veröffentlichen neue Nachricht auf Kanal responseclient Dies ist für den Beispielcode:

ioApp.on ('connection' , function(socket) { 
redisSub.on('new_request', function (channel, message) { 
    console.log(channel + ':' + message); 

    redisPub.publish("responseclient", JSON.stringify(res));  

}); 

})

Diese Arbeit reibungslos, wenn Benutzer B zu Socket.IO Verbunden ist. Aber wenn Benutzer B offline war oder nicht verbunden ist Socket.io, dies wird für lange warten, bis wir manuell zu töten oder bis der Benutzer B ist online

Was ich für mich fragen, sind:

  1. Können wir etwas wie ein callback auf Redis Pub/Sub erstellen? Wenn der Teilnehmer die Nachricht nicht akzeptiert, aufgrund von Offline oder etwas anderem, schließen wir die Verbindung. Ist das möglich ?
  2. In Node.Js weiß ich, ich kann Timeout-Funktion verwenden, die das Subskribieren schließen oder jedes Ereignis ausstrahlen wird, wenn zu einer bestimmten Zeit keine Nachricht empfangen wurde, wie dies auf Golang zu tun? Ich muss die User A informieren, wenn User B aktiv oder offline ist, so dass er eine weitere Zeit warten kann, um eine Anfrage zu erstellen.
  3. Wenn nichts kann, was ist dein Vorschlag für mich, dies zu tun?

Ich hoffe meine Frage, verständlich, und kann gut beantwortet werden.
* Einige Code möglicherweise, fehlende Variable.
** Ich verwende diese Bibliothek für Goland Redis: go-redis

+1

Für die erste Frage ist die Antwort nein: http://stackoverflow.com/questions/23675394/redis-publish-subscribe-is-redis-guaranteed-to-deliver-the-message-even-under-m . Sehen Sie sich antirezs Kommentar für eine mögliche Lösung an –

+0

Danke für die Antwort. Auf der Suche nach ACK vielleicht eine andere Lösung für mich. Weil ich auf die Antwort der zweiten Frage warte Hehe: D –

Antwort

1

1) Es gibt keine Rückrufe in Redis.

2) Der übliche Weg, um ein Timeout in Go zu implementieren, ist die Verwendung von Channels und Auswahl - wo ein Kanal ist, wo Sie die Blockierung durchführen und ein anderer Kanal eine Nachricht beim Timeout empfängt.Beispiele davon finden Sie here und here for the docs

Jetzt für (3), haben Sie einige Optionen auf Methoden. Die erste besteht darin, eine Liste zu verwenden, von einer Seite zu pushen (Publizieren) und von einer anderen zu poppen (Abonnieren). Für den Empfänger verwenden Sie wild BRPOP - Pop von rechts oder links jeweils zu blockieren. Sie können beide kombinieren, um persistente Nachrichten zu erhalten.

Nun hängt ein Teil von PUBSUB auch davon ab, was Sie veröffentlichen. Wenn Sie in einem Kanal veröffentlichen, der einen Abonnenten hätte wenn und nur wenn ein Benutzer verbunden ist, um es zu empfangen (und somit ein und nur ein Abonnent für diesen Kanal), können Sie die Antwort von Ihrem Veröffentlichungsbefehl überprüfen. Es wird Ihnen sagen, wie viele Clients es veröffentlicht wurde. Wenn der Kanal nur von einem Online-Empfänger abonniert wird, erhalten Sie eine "1" zurück und eine "0", wenn der Benutzer offline war.

Ein drittes Beispiel ist das Speichern der Nachrichten in einer sortierten Menge mit dem Zeitstempel als Punktestand. Dies würde es dem Empfänger ermöglichen, eine Verbindung herzustellen und Nachrichten von dem letzten Zeitpunkt zu erhalten, an dem er verbunden war - aber das setzt eine gewisse Persistenz von diesem irgendwo voraus - normalerweise der Client. Sie benötigen außerdem eine Bereinigungsaktivität für die sortierten Sätze. In diesem Szenario sollten Sie auch die Replikation berücksichtigen. In diesem Fall müssen Sie Failovers explizit berücksichtigen. In dem Szenario, das Sie beschreiben, sollten Sie jedoch Verbindungen und Verbindungen wiederherstellen. Es gibt spezifische Beispiele dafür unter my post on reliable PUBSUB.

+0

Danke für die Antwort. Der schnellste Weg, um für mich zu tun ist, indem Sie auf Kanal wählen. –