如何通知HTTP服务器成功启动

时间:2018-11-16 06:38:27

标签: go

我正在尝试在Go中启动HTTP服务器,并且当服务器启动时,应该打印一条消息,如果出现错误,应该打印一条错误消息。

给出以下代码:

const (
    HTTPServerPort = ":4000"
)

func main() {
    var httpServerError = make(chan error)
    var waitGroup sync.WaitGroup

    setupHTTPHandlers()

    waitGroup.Add(1)
    go func() {
        defer waitGroup.Done()

        httpServerError <- http.ListenAndServe(HTTPServerPort, nil)
    }()

    if <-httpServerError != nil {
        fmt.Println("The Logging API service could not be started.", <-httpServerError)
    } else {
        fmt.Println("Logging API Service running @ http://localhost" + HTTPServerPort)
    }

    waitGroup.Wait()
}

当我启动应用程序时,我看不到要打印到控制台的任何内容:

Logging API Service running @ http://localhost:4000

当我将端口更改为无效端口时,以下输出将输出到控制台:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]: main.main() ...app.go:45 +0x107 exit status 2

有人能指出我正确的方向,以便让我知道我在执行此操作时做错了什么吗?

2 个答案:

答案 0 :(得分:2)

除非更改代码中的逻辑或分别使用ListenServe,否则您将无法执行此操作。因为ListenAndServe是一个阻塞函数。如果发生意外情况,它将返回一个错误。如果不是这样,它将继续阻止服务器运行。启动服务器时都不会触发任何事件。

然后让我们分别运行ListenServe

l, err := net.Listen("tcp", ":8080")
if err != nil {
    // handle error
}

// Signal that server is open for business. 

if err := http.Serve(l, rootHandler); err != nil {
    // handle error
}

请参见https://stackoverflow.com/a/44598343/4792552

P.S。 net.Listen不会阻止,因为它在后台运行。换句话说,它只是生成OS级别的套接字连接,并向您返回其详细信息/ ID。因此,您可以使用该ID将订单代理到该套接字。

答案 1 :(得分:1)

问题是您的if语句将始终从httpServerError通道读取。但是,只有当服务器发生故障时,才会向其中写入内容。

尝试使用select语句:

select{
case err := <-httpServerError
    fmt.Println("The Logging API service could not be started.", err)
default:
    fmt.Println("Logging API Service running @ http://localhost" + HTTPServerPort
}

如果频道上没有任何内容,将运行default情况。

请注意,您的示例不会两次从通道读取该消息。从通道读取值后,它就消失了。把它当成队列。