您正在开发一个使用 OAuth 与 Instagram API 交互的命令行机器人,该机器人未针对命令行进行优化应用程序。为了克服这个问题,您设置了一个本地 HTTP 服务器作为授权的重定向 URI。用户授权应用程序并重定向到服务器后,您希望在显示访问令牌后关闭服务器。
您在实现关闭机制时遇到了问题。具体来说,在请求处理程序 (showTokenToUser) 中调用 srv.Shutdown(nil) 会导致错误:
2017/11/23 16:02:03 Httpserver: ListenAndServe() error: http: Server closed 2017/11/23 16:02:03 http: panic serving [::1]:61793: runtime error: invalid memory address or nil pointer dereference
出现问题是因为您正在调用 srv.Shutdown(nil)多次:
调用当服务器仍在侦听连接时 srv.Shutdown 会导致竞争状况。 ListenAndServe() goroutine 尝试关闭打开的侦听器和空闲连接,但它被处理程序闭包中对 Shutdown 的后续调用中断。这种状态不一致会触发恐慌。
要解决此问题,您可以使用以下两种方法之一:
1.使用 context.WithCancel:
在此方法中,您将创建一个带有取消函数的 context.Context。上下文被传递给 ListenAndServe goroutine 和 showTokenToUser 处理函数。在处理程序内部,当访问令牌已显示给用户时,您可以调用取消函数来终止上下文。当上下文被取消时,ListenAndServe goroutine 将优雅地关闭服务器。
2.使用相同的 Context:
您可以将相同的 context.Context 传递给 ListenAndServe goroutine 和处理函数,而不是调用 context.WithCancel。当显示访问令牌时,您在上下文上调用 cancel(),这将触发处理程序和 ListenAndServe goroutine 的关闭。
实现任一方法后,请记住等待 srv.Shutdown 函数在退出程序之前完成。
以上是返回响应后如何优雅地关闭 HTTP 服务器?的详细内容。更多信息请关注PHP中文网其他相关文章!