ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 监听和服务 你可以启动服务器以侦听任何类型的 `net.Listener`  甚至 `http.Server` 实例。 服务器的初始化方法应在最后通过 `Run` 函数传递。 Go开发人员用来为其服务器提供服务的最常见方法是传递一个以“ hostname:ip”形式出现的网络地址。对于Iris,我们使用 `iris.Addr`,它是一个 `iris.Runner` 类型。 ``` // 侦听网络地址为 0.0.0.0:8080 的 tcp 协议 app.Run(iris.Addr(":8080")) ``` 有时候你已经在应用程序中创建了标准的 net/http 服务,并希望使用该服务器为 Iris Web 应用程序提供服务。 ``` // 与前面相同,但使用的自定义 http.Server 也可能在其他地方使用 app.Run(iris.Server(&http.Server{Addr:":8080"})) ``` 最高级的用法是创建自定义或标准 `net.Listener` 并将其传递给 `app.Run`。 ``` // 用自定义的 net.Listener l, err := net.Listen("tcp4", ":8080") if err != nil { panic(err) } app.Run(iris.Listener(l)) ``` 一个更完整的示例,使用 unix-only socket 文件功能。 ``` package main import ( "os" "net" "github.com/kataras/iris/v12" ) func main() { app := iris.New() // UNIX socket if errOs := os.Remove(socketFile); errOs != nil && !os.IsNotExist(errOs) { app.Logger().Fatal(errOs) } l, err := net.Listen("unix", socketFile) if err != nil { app.Logger().Fatal(err) } if err = os.Chmod(socketFile, mode); err != nil { app.Logger().Fatal(err) } app.Run(iris.Listener(l)) } ``` UNIX 和 BSD hosts 可以利用重用端口功能 ``` package main import ( // tcplisten 包提供可自定义的 TCP net.Listener , 其中包含各种 // 与性能相关的选项: // // - SO_REUSEPORT.。 此选项允许线性扩展服务器性能 // 在多CPU服务器上。 // 有关详细信息,请参见 https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1/ 。 // // - TCP_DEFER_ACCEPT。 此选项希望服务器从接受的文件中读取 // 在写入之前先进行连接。 // // - TCP_FASTOPEN.。 有关详细信息,请参见 https://lwn.net/Articles/508865/ for details 。 "github.com/valyala/tcplisten" "github.com/kataras/iris/v12" ) // go get github.com/valyala/tcplisten // go run main.go func main() { app := iris.New() app.Get("/", func(ctx iris.Context) { ctx.HTML("<h1>Hello World!</h1>") }) listenerCfg := tcplisten.Config{ ReusePort: true, DeferAccept: true, FastOpen: true, } l, err := listenerCfg.NewListener("tcp", ":8080") if err != nil { app.Logger().Fatal(err) } app.Run(iris.Listener(l)) } ``` ### [HTTP/2 和安全](https://github.com/kataras/iris/wiki/Host#http2-and-secure) 如果你已签名文件密钥,则可以基于这些证书密钥使用 `iris.TLS` 服务 `https` 。 ``` // TLS 使用密钥文件 app.Run(iris.TLS("127.0.0.1:443", "mycert.cert", "mykey.key")) ``` 当应用准备好 [生产] 时,应该使用的方法是 `iris.AutoTLS` 启动安全服务器。 由 [https://letsencrypt.org](https://letsencrypt.org/) **免费** 提供。 ``` // 自动 TLS app.Run(iris.AutoTLS(":443", "example.com", "admin@example.com")) ``` ### [Any `iris.Runner`](https://github.com/kataras/iris/wiki/Host#any-irisrunner) 有时候可能希望聆听非常特殊的内容,而不是 `net.Listener` 类型。可以通过 `iris.Raw` 来做到这一点,但是你要对这种方法负责 ``` // 使用任何 func() 错误, // 启动倾听者的责任由你这样决定, // 为了简单起见,我们将使用 // "net/http" 包的 ListenAndServe 方法。 srv := &http.Server{Addr:":8080"} app.Run(iris.Raw(srv.ListenAndServe)) ``` ## [Host 配置](https://github.com/kataras/iris/wiki/Host#host-configurators) 以上所有形式的监听都接受 `func(* iris.Supervisor)` 的最后一个可变参数。这个参数用于给通过这些方法传递的特定主机添加配置。 例如,假设我们要添加一个在服务器关闭时触发的回调 ``` app.Run(iris.Addr(":8080", func(h *iris.Supervisor) { h.RegisterOnShutdown(func() { println("server terminated") }) })) ``` 甚至可以在 `app.Run` 方法之前执行此操作,但区别在于这些 host 配置程序将被执行到可用于为Web应用提供服务的所有 host (通过 `app.NewHost` 一会儿我们就可以看到) ``` app := iris.New() app.ConfigureHost(func(h *iris.Supervisor) { h.RegisterOnShutdown(func() { println("server terminated") }) }) app.Run(iris.Addr(":8080")) ``` 在`Run`方法之后,可以通过 `Application#Hosts` 字段设置应用程序提供服务的所有 host 的访问权限。 但是最常见的情况是,你可能需要在 `app.Run` 方法之前访问 host,有两种方法可以访问 host 管理器,请参见下文。 我们已经了解了如何通过 `app.Run` 或 `app.ConfigureHost` 的第二个参数配置所有应用程序的 host 。还有一种更适合简单场景的方法,即使用 `app.NewHost` 创建新 host 并使用它的 `Serve` 或者 `Listen` 方法通过 `iris#Raw` Runner 启功应用程序。 请注意,这种方式需要额外引入 `net/http` 包。 示例代码: ``` h := app.NewHost(&http.Server{Addr:":8080"}) h.RegisterOnShutdown(func(){ println("server terminated") }) app.Run(iris.Raw(h.ListenAndServe)) ``` ## [多 hosts](https://github.com/kataras/iris/wiki/Host#multi-hosts) 你可以使用多个服务器来服务 Iris Web 应用,  `iris.Router` 与 `net/http/Handler` 方法兼容。因此 ,如你所知道的那样, 它可用于在任何`net / http` 服务器上进行改造,但是有一种更简单的方法,使用 `app.NewHost`复制所有 host 配置程序并通过  `app.Shutdown` 关闭所有连接到特定 Web 应用程序的 host 。 ``` app := iris.New() app.Get("/", indexHandler) // 以不同的 goroutine 运行,来防止主 "goroutine" 不被干扰。 go app.Run(iris.Addr(":8080")) // 启动第二台正在监听 tcp 0.0.0.0:9090 的服务器, // 不带 "go" 关键字,因为我们要在上次服务器运行时阻塞。 app.NewHost(&http.Server{Addr:":9090"}).ListenAndServe() ``` ## [关机 (正常)](https://github.com/kataras/iris/wiki/Host#shutdown-gracefully) 让我们继续学习如何捕获 CONTROL+C/COMMAND+C 或者 unix kill 命令并正常关闭服务器。 > 通过 CONTROL+C/COMMAND+C 正常关机或者当 kill 命令被设置为 ENABLED BY-DEFAULT 的时候。 为了手动管理应用中断时要执行的操作,我们需要通过 `WithoutInterruptHandler` 禁用默认行为并注册一个新的中断处理程序 (全局的, 在所有可用 hosts 上的)。 示例代码: ``` package main import ( "context" "time" "github.com/kataras/iris/v12" ) func main() { app := iris.New() iris.RegisterOnInterrupt(func() { timeout := 5 * time.Second ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() // 关闭所有 hosts app.Shutdown(ctx) }) app.Get("/", func(ctx iris.Context) { ctx.HTML(" <h1>hi, I just exist in order to see if the server is closed</h1>") }) app.Run(iris.Addr(":8080"), iris.WithoutInterruptHandler) } ``` 继续阅读 [配置](https://github.com/kataras/iris/wiki/Configuration) 章节, 以了解`app.Run` 的第二个可变参数。