So stoppen Sie einen Listening-Server in Go ordnungsgemäß
In Go blockiert die listen.Accept-Funktion die Ausführung, was das Beenden eines Servers schwierig macht Server ordnungsgemäß abhören. Um zu bestimmen, wann der Server beendet werden muss, besteht ein Ansatz darin, den Listening-Socket zu schließen und den spezifischen Fehler zu erkennen, der auf eine geschlossene Netzwerkverbindung hinweist. Allerdings wird dieser Fehler nicht vom Net-Paket exportiert, sodass Entwickler auf eine umständliche Fehlerbehandlung zurückgreifen müssen.
Glücklicherweise gibt es eine elegantere Lösung. Durch die Verwendung eines fertigen Kanals können Sie dem Server signalisieren, dass er anhalten soll, bevor die Verbindung geschlossen wird. So kann es mit Beispielcode implementiert werden:
package main import ( "io" "log" "net" "sync" "time" ) // Echo server struct type EchoServer struct { listen net.Listener done sync.WaitGroup } // Respond to incoming connection // // Write the address connected to then echo func (es *EchoServer) respond(remote *net.TCPConn) { defer remote.Close() _, err := io.Copy(remote, remote) if err != nil { log.Printf("Error: %s", err) } } // Listen for incoming connections func (es *EchoServer) serve() { for { conn, err := es.listen.Accept() if err != nil { select { case <-es.done: // Server has been stopped, so we can exit without showing the error. default: log.Printf("Accept failed: %v", err) } return } es.done.Add(1) // Increment the waitgroup for each incoming connection go func() { es.respond(conn.(*net.TCPConn)) es.done.Done() // Decrement the waitgroup when done handling the connection }() } } // Stop the server by closing the listening listen func (es *EchoServer) stop() { es.done.Wait() // Wait for all outstanding connections to finish handling es.listen.Close() // Now it the Accept will have an error above } // Make a new echo server func NewEchoServer(address string) *EchoServer { listen, err := net.Listen("tcp", address) if err != nil { log.Fatalf("Failed to open listening socket: %s", err) } es := &EchoServer{ listen: listen, } es.done.Add(1) go es.serve() return es } // Main func main() { log.Println("Starting echo server") es := NewEchoServer("127.0.0.1:18081") // Run the server for 1 second time.Sleep(1 * time.Second) // Close the server log.Println("Stopping echo server") es.stop() }
In diesem Code beendet die Serve-Funktion den Server ordnungsgemäß, indem sie zurückkehrt, wenn auf dem Fertig-Kanal ein Wert empfangen wird. Die Hauptfunktion zeigt, wie Sie den Server starten, auf Verbindungen warten und ihn dann ordnungsgemäß beenden. Durch die Verwendung eines fertigen Kanals wird die Fehlerbehandlung sauber von der Abschaltlogik getrennt, was zu einem besser wartbaren und fehlerfreien Server führt.
Das obige ist der detaillierte Inhalt vonWie kann ich einen Go-Listening-Server ordnungsgemäß herunterfahren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!