跳到主要内容
版本:2.6.x

GoFrame 是一款基础设施建设比较完善的模块化框架, WebServer 模块是其中比较核心的模块,我们这里将 Web 服务开发作为框架入门的选择,便于大家更容易学习和理解。

GoFrame 框架提供了非常强大的 WebServer,由 ghttp 模块实现。实现了丰富完善的相关组件,例如: RouterCookieSession、路由注册、配置管理、模板引擎、缓存控制等等,支持热重启、热更新、多域名、多端口、多实例、 HTTPSRewritePProf 等等特性。

接口文档地址:

https://pkg.go.dev/github.com/gogf/gf/v2/net/ghttp

哈喽世界

老规矩,我们先来一个 Hello World

package main

import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)

func main() {
s := g.Server()
s.BindHandler("/", func(r *ghttp.Request) {
r.Response.Write("哈喽世界!")
})
s.Run()
}

这便是一个最简单的服务,默认情况下它不支持静态文件处理,只有一个功能,访问 http://127.0.0.1/ 的时候,它会返回 哈喽世界!

任何时候,您都可以通过 g.Server() 方法获得一个默认的 Server 对象,该方法采用 单例模式 设计,也就是说,多次调用该方法,返回的是同一个 Server 对象。通过 Run() 方法执行 Server 的监听运行,在没有任何额外设置的情况下,它默认监听 80 端口。

关于其中的路由注册,我们将会在后续的章节中介绍,我们继续来看看如何创建一个支持静态文件的 Server

静态服务

创建并运行一个支持静态文件的 WebServer

package main

import (
"github.com/gogf/gf/v2/frame/g"
)

func main() {
s := g.Server()
s.SetIndexFolder(true)
s.SetServerRoot("/home/www/")
s.Run()
}

创建了 Server 对象之后,我们可以使用 Set* 方法来设置 Server 的属性,我们这里的示例中涉及到了两个属性设置方法:

  1. SetIndexFolder 用来设置是否允许列出 Server 主目录的文件列表(默认为 false)。
  2. SetServerRoot 用来设置 Server 的主目录(类似 nginx 中的 root 配置,默认为空)。

Server 默认情况下是没有任何主目录的设置,只有设置了主目录,才支持对应主目录下的静态文件的访问。

多端口监听

Server 同时支持多端口监听,只需要往 SetPort 参数设置多个端口号即可(当然,针对于 HTTPS 服务,我们也同样可以通过 SetHTTPSPort 来设置绑定并支持多个端口号的监听, HTTPS 服务的介绍请参看后续对应章节)。

我们来看一个例子:

package main

import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)

func main() {
s := g.Server()
s.BindHandler("/", func(r *ghttp.Request){
r.Response.Writeln("go frame!")
})
s.SetPort(8100, 8200, 8300)
s.Run()
}

执行以上示例后,我们访问以下URL将会得到期望的相同结果:

http://127.0.0.1:8100/
http://127.0.0.1:8200/
http://127.0.0.1:8300/

多实例支持

Server 支持同一进程多实例运行,下面我们来看一个例子:

package main

import (
"github.com/gogf/gf/v2/frame/g"
)

func main() {
s1 := g.Server("s1")
s1.SetPort(8080)
s1.SetIndexFolder(true)
s1.SetServerRoot("/home/www/static1")
s1.Start()

s2 := g.Server("s2")
s2.SetPort(8088)
s2.SetIndexFolder(true)
s2.SetServerRoot("/home/www/static2")
s2.Start()

g.Wait()
}

可以看到我们在支持多个 Server 的语句中,给 g.Server 方法传递了不同的单例名称参数,该参数用于标识不同的 Server 实例,因此需要保证唯一性。如果需要获取同一个 Server 实例,那么传入同一个名称即可。例如在多个 goroutine 中,或者不同的模块中,都可以通过 g.Server 获取到同一个 Server 实例。

域名绑定

Server 支持多域名绑定,并且不同的域名可以绑定不同的服务。

我们来看一个简单的例子:

package main

import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)

func Hello1(r *ghttp.Request) {
r.Response.Write("127.0.0.1: Hello1!")
}

func Hello2(r *ghttp.Request) {
r.Response.Write("localhost: Hello2!")
}

func main() {
s := g.Server()
s.Domain("127.0.0.1").BindHandler("/", Hello1)
s.Domain("localhost").BindHandler("/", Hello2)
s.Run()
}

我们访问 http://127.0.0.1/http://localhost/ 可以看输出不同的内容。

此外, Domain 方法支持多个域名参数,使用英文“,”号分隔,例如:

s.Domain("localhost1,localhost2,localhost3").BindHandler("/", Hello2)

这条语句的表示将 Hello2 方法注册到指定的3个域名中( localhost1~3),对其他域名不可见。

需要注意的是: Domain 方法的参数必须是 准确的 域名, 不支持泛域名形式,例如: *.goframe.org 或者 .goframe.org 是不支持的, api.goframe.org 或者 goframe.org 才被认为是正确的域名参数。

路由特性

Server 提供了非常出色的路由特性,我们先来看一个简单的示例:

package main

import (
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/frame/g"
)

func main() {
s := g.Server()
s.BindHandler("/{class}-{course}/:name/*act", func(r *ghttp.Request) {
r.Response.Writef(
"%v %v %v %v",
r.Get("class"),
r.Get("course"),
r.Get("name"),
r.Get("act"),
)
})
s.SetPort(8199)
s.Run()
}

这是一个混合的路由规则示例,用于展示某个班级、某个学科、某个学生、对应的操作,运行后,我们可以通过例如该地址: http://127.0.0.1:8199/class3-math/john/score 看到测试结果。在页面上你可以看得到对应的路由规则都被一一解析,业务层可以根据解析的参数进行对应的业务逻辑处理。 具体的路由注册管理介绍请查看后续 路由管理-路由规则 章节。

配置管理

GoFrame 的核心组件均实现了便捷的配置管理特性,仅需通过配置文件的修改即可实现组件的功能配置。大多数的场景中我们推荐使用配置文件来管理组件的配置, Server 的配置请查看 服务配置 章节。

平滑重启

Server 内置支持平滑重启特性,详细介绍请参考 平滑重启特性 章节。

HTTPS支持

Server 支持 HTTPS 服务,并且也同时支持单进程提供 HTTP&HTTPS 服务,HTTPS的详细介绍请参考 HTTPS&TLS 章节。

更多功能特性

更多功能及特性请继续阅读后续章节。