Go 的 net 套件提供了創建監聽伺服器的能力。然而,由於listen.Accept方法的阻塞性質,優雅地停止這些伺服器可能具有挑戰性。
停止伺服器的常見方法是關閉偵聽套接字。但是,這可能會導致在連接接受期間無法將錯誤與真正的錯誤區分開來。因此,以下程式碼片段顯示了此問題:
// ... // Listen for incoming connections func (es *EchoServer) serve() { for { conn, err := es.listen.Accept() // FIXME: I'd like to detect "use of closed network connection" here // FIXME: but it isn't exported from net if err != nil { log.Printf("Accept failed: %v", err) break } // ... } // ... }
為了解決此限制,我們可以利用 es.done 通道在伺服器啟動之前發送訊號停了下來。以下是程式碼的改進方法:
// ... // Listen for incoming connections func (es *EchoServer) serve() { for { conn, err := es.listen.Accept() if err != nil { select { case <-es.done: // Server is being stopped, so we can exit without logging the error. default: log.Printf("Accept failed: %v", err) } return } // ... } } // Stop the server by closing the listening socket func (es *EchoServer) stop() { es.done <- true es.listen.Close() }
透過在關閉監聽套接字之前向es.done 通道發送一個值,serve 函數可以確定伺服器何時停止並正常退出,而不會記錄虛假訊息錯誤。
以上是如何優雅地停止 Go 監聽伺服器而不出現虛假錯誤?的詳細內容。更多資訊請關注PHP中文網其他相關文章!