Wie der broadcast-Nachricht über den Kanal
Bin ich neu zu gehen, und ich bin versucht, zu erstellen eine einfache chat-server, wo die clients können broadcast-Nachrichten an alle verbundenen clients.
In meinem server, ich habe eine goroutine (unendliche Schleife) akzeptiert die Verbindung und alle verbindungen erhalten werden, die durch einen Kanal.
go func() {
for {
conn, _ := listener.Accept()
ch <- conn
}
}()
Dann starte ich eine Prozedur (goroutine) für jeden angeschlossenen client. Innerhalb der handler, die ich versuche zu broadcast an alle Anschlüsse durch Durchlaufen durch den Kanal.
for c := range ch {
conn.Write(msg)
}
Kann ich jedoch nicht übertragen, da (ich glaube aus der Lektüre der Dokumente) der Kanal muss geschlossen werden, bevor die Iteration. Ich bin nicht sicher, wenn ich sollte, schließen Sie den Kanal, denn ich möchte ständig neuen verbindungen akzeptiert und schließen der Kanal wird nicht lass mich das machen. Wer kann mir helfen, oder eine bessere Möglichkeit, broadcast-Nachrichten an alle verbundenen clients, würde es geschätzt werden.
for c:= range ch
- Schleife wird nicht beendet, bis ch ist geschlossen, aber das ist alles.InformationsquelleAutor Jin Hoon Jeffrey Bang | 2016-04-05
Du musst angemeldet sein, um einen Kommentar abzugeben.
Was Sie tun, ist die fan-out-Muster, das heißt, mehrere Endpunkte sind das Zuhören zu einem einzigen Eingangssignal. Das Ergebnis dieses Muster ist nur einer dieser Zuhörer wird in der Lage sein, um die Nachricht, wenn es eine message in die input-Quelle. Die einzige Ausnahme ist ein
close
des Kanals. Dieseclose
wird erkannt werden, indem alle Listener, und damit ein "broadcast".Aber das, was Sie tun möchten, ist das broadcasting eine Nachricht Lesen, von Verbindung, so könnten wir so etwas tun:
, Wenn die Anzahl der Zuhörer ist bekannt
Lassen jeden Arbeiter hören dedizierte broadcast-Kanal, und versenden Sie die Nachricht von der Haupt-Kanal für dedizierte broadcast-Kanal.
Dann könnten wir haben eine Reihe der Arbeitnehmer:
Dann beginnen unsere Hörer:
Und ein dispatcher:
, Wenn die Anzahl der Zuhörer ist nicht bekannt
In diesem Fall, die Lösung oben funktioniert immer noch. Der einzige Unterschied ist, Wann immer Sie eine neue Arbeiter, die Sie benötigen, um erstellen Sie eine neue Arbeiter, starten Sie es und schieben Sie es in
workers
Scheibe. Aber diese Methode erfordert eine thread-sichere Scheibe, die eine Sperre um ihn herum. Eine von der Implementierung kann wie folgt Aussehen:Wann immer Sie starten möchten, ein Arbeiter:
Und dispatcher, wird wie folgt geändert:
Letzten Worte: lassen Sie niemals einen baumelnden goroutine
Einer von den guten Praktiken ist: lassen Sie niemals einen baumelnden goroutine. Also, wenn Sie fertig hören, müssen Sie schließen Sie alle von der goroutines Sie gefeuert. Dies geschieht über
quit
Kanal inworker
:Müssen wir zunächst erstellen Sie eine Globale
quit
Signalisierungskanal:Werden und Wann immer wir erstellen einen worker, weisen wir die
globalQuit
Kanal, um es, wie Sie die quit-signal:Dann, wenn wir wollen, Herunterfahren alle Arbeiter, die wir einfach tun:
Seit
close
wird von allen anerkannt hören goroutines (dies ist der Punkt, den du verstanden), alle goroutines zurückgegeben werden. Denken Sie daran, schließen Sie Ihre dispatcher-routine als gut, aber ich lass es Euch 🙂der einfachste Weg zu beginnen ist ein
worker
und dann schieben Sie es inworkers
slice, dann wird es ausgestrahlt werden, wenn die nächste Zeit für die loop-in-dispatcher ausgeführt wird. Erinnern Sie sich sperren, wenn man dabei die Scheibe drücken 🙂Ich machte einen Kern aus", wenn die Anzahl der Zuhörer ist nicht wissen" Beispiel, wie der code war nicht komplett und fehlerhaft war. Dies ist ein einfacher server, der auf broadcasts ganzen zahlen, erzeugt aus einer goroutine, jeder Verbindung gesendet, die Daten über den Rundfunk : gist.github.com/speps/ce645a5ca2d2cb9a81e52c7311f38677
Wer soll in der Nähe der Arbeiter.Quelle chan?
InformationsquelleAutor nevets
Eine elegantere Lösung ist ein "broker", wo die Kunden abonnieren können, und unsubscibe Nachrichten.
Zu handhaben auch das abonnieren und abbestellen von Newslettern aus, wir können Kanäle nutzen, so die main-loop des Brokers der erhält und verteilt die Nachrichten integrieren können all diese mit einem einzigen
select
- Anweisung, und die Synchronisation ist gegeben, von der Lösung der Natur.Ein weiterer trick ist die Speicherung der Abonnenten in einer map, mapping aus dem Kanal, den wir verwenden zum verteilen von Nachrichten an Sie. Nutzen Sie also den Kanal als Schlüssel in der map, und klicken Sie dann hinzufügen und entfernen des clients ist "tot" einfach. Möglich ist dies, da Kanal-Werte sind vergleichbar, und Ihr Vergleich ist sehr effizient, da-channel-Werte sind einfach Zeiger auf die Kanal-Deskriptoren.
Ohne weitere Umschweife, hier ist eine einfache broker-Implementierung:
Beispiel mit:
Ausgabe des obigen wird (versuchen Sie es auf die Gehen Spielplatz):
Verbesserungen
Können Sie prüfen, die folgenden Verbesserungen. Diese können oder möglicherweise nicht nützlich sein, je nachdem, wie /auf was Sie der broker.
Broker.Unsubscribe()
können die Meldung schließen, Kanal, der signalisiert, dass keine Nachrichten mehr gesendet werden:Dies würde es ermöglichen, Kunden zu
range
über die Nachricht, Kanal, so wie hier:Dann, wenn jemand kündigt diese
msgCh
wie diese:Den oben genannten Bereich Schleife wird beendet, nachdem die Verarbeitung aller Nachrichten, die gesendet wurden, bevor der Anruf zu
Unsubscribe()
.Wenn Sie möchten, dass Ihre Kunden verlassen sich auf die message channel geschlossen wird, und der Makler Lebensdauer ist schmaler als die Ihrer app ist lifetime, dann könnte man auch schließen Sie alle abonnierten clients, wenn der Makler ist angehalten, in der
Start()
Methode wie diese:InformationsquelleAutor icza
Sendung an einem Stück Kanal und synchronisiert.Mutex zu verwalten-Kanal hinzufügen und entfernen kann, kann das der einfachste Weg in deinem Fall.
Hier ist was Sie tun können, um
broadcast
in golang:InformationsquelleAutor bronze man
Da Gehen Kanäle Folgen der Communicating Sequential Processes (CSP) - Muster, die Kanäle sind eine Punkt-zu-Punkt-Kommunikation Einheit. Es ist immer ein Schriftsteller und ein Leser beteiligten in jeder exchange.
Jedoch, jeder Kanal Ende werden kann gemeinsamen unter mehreren goroutines. Das ist sicher zu tun - es ist keine gefährliche Rasse Zustand.
Also, es können mehrere Autoren teilen die schreiben Ende. Und/oder es können mehrere Leser teilen die Lesung zu Ende. Ich schrieb diese andere Antwort, die enthält Beispiele.
Wenn Sie wirklich brauchen, eine Sendung, können Sie das direkt tun, aber es ist nicht schwer zu implementieren, eine intermediate-goroutine, kopiert einen Wert aus, um jeweils eine Gruppe der Kanäle.
InformationsquelleAutor Rick-777