gin 组件
把 gin 封装成 Cherry 组件,为节点提供 HTTP 服务能力:路由、静态文件、模板渲染和常用中间件。
这是框架唯一的 HTTP Server
Cherry 核心仓库不提供 HTTP 连接器,需要对外提供 HTTP 接口时使用本组件。它和 连接器 是两条独立的路径——连接器面向游戏长连接,gin 组件面向普通 HTTP 请求。
安装
bash
go get github.com/cherry-game/components/gin@latest注册组件
go
import (
"github.com/cherry-game/cherry"
cherryGin "github.com/cherry-game/components/gin"
)
func main() {
app := cherry.Configure("./config/profile.json", "web-1", false, cherry.Cluster)
httpServer := cherryGin.NewHttp("http_server", "127.0.0.1:8081")
httpServer.Use(cherryGin.Cors())
httpServer.Use(cherryGin.RecoveryWithZap(true))
httpServer.Use(cherryGin.MaxConnect(1024))
httpServer.Static("/static", "./static/")
httpServer.LoadHTMLFiles("./view/index.html")
httpServer.Register(new(MyController))
app.Register(httpServer)
app.Startup()
}组件的名称是 gin_component_ 加上你传入的 name,所以同一个进程可以注册多个 HTTP 服务,用不同的名字区分。
构造函数
| 函数 | 说明 |
|---|---|
NewHttp(name, address string) *Component | HTTP 服务 |
NewHttps(name, address, certFile, keyFile string) *Component | HTTPS 服务 |
New(name, address string, opts ...OptionFunc) *Component | 通用构造,支持更多选项 |
编写 Controller
Controller 需要实现 IController 接口,嵌入 BaseController 可以省掉样板代码:
go
type IController interface {
PreInit(app cfacade.IApplication, engine *gin.Engine) // 注入 App 和 Engine
Init() // 路由注册写在这里
Stop()
}go
type MyController struct {
cherryGin.BaseController
}
func (t *MyController) Init() {
t.GET("/", t.index)
t.POST("/register", t.register)
t.Any("/hello", t.hello)
// 分组路由
group := t.Group("/api")
group.GET("/list", t.list)
}
// 用 cherryGin.Context,它提供了常用的取值与响应方法
func (t *MyController) index(c *cherryGin.Context) {
c.RenderHTML("this is index...")
}
func (t *MyController) register(c *cherryGin.Context) {
name := c.GetString("name", "")
c.JSON200(map[string]any{"name": name})
}
// 也可以直接用原生 gin.HandlerFunc
func (t *MyController) raw(c *gin.Context) {
c.String(http.StatusOK, "ok")
}BaseController 提供 GET / POST / Any / Group,并且 App 和 Engine 字段会在 PreInit 时自动注入——需要用到原生 gin 能力时直接用 t.Engine。
中间件
| 中间件 | 说明 |
|---|---|
GinDefaultZap() | 默认的 Zap 日志 |
GinZap(timeFormat string, utc bool) | 自定义时间格式的 Zap 日志 |
RecoveryWithZap(stack bool) | panic 恢复 + 记录堆栈 |
Cors(domain ...string) | 跨域,可指定允许的域名 |
MaxConnect(n int) | 限制最大并发连接数 |
生产环境务必加上 RecoveryWithZap
没有它的话,一个 handler 里的 panic 会直接中断请求。加上之后会恢复并记录堆栈,便于排查。
静态文件与模板
go
httpServer.Static("/static", "./static/") // 目录映射
httpServer.StaticFile("/favicon.ico", "./favicon.ico") // 单文件映射
httpServer.LoadHTMLFiles("./view/index.html") // 加载模板(来自内嵌的 gin.Engine)服务器选项
go
httpServer := cherryGin.NewHttp("http_server", ":8081",
cherryGin.WithReadTimeout(10*time.Second),
cherryGin.WithReadHeaderTimeout(5*time.Second),
cherryGin.WithIdleTimeout(60*time.Second),
cherryGin.WithMaxHeaderBytes(1<<20),
)| 选项 | 说明 |
|---|---|
WithReadTimeout(d) | 读超时 |
WithReadHeaderTimeout(d) | 读请求头超时 |
WithIdleTimeout(d) | 空闲连接超时 |
WithMaxHeaderBytes(n) | 请求头上限 |
WithCert(certFile, keyFile) | TLS 证书 |
运行模式默认是 gin.ReleaseMode,开发时可切换:
go
cherryGin.SetMode(gin.DebugMode)请求上下文
cherryGin.Context 内嵌了 *gin.Context,并提供一组带默认值的便捷方法:
| 分类 | 方法 |
|---|---|
| 参数取值 | GetParams、GetBody、IsPost、IsGet |
| 通用取值 | GetBool、GetInt、GetInt32、GetInt64、GetString |
| 表单取值 | PostInt、PostInt32、PostInt64、PostString |
| 数组取值 | PostFormIntArray、PostFormInt32Array、PostFormInt64Array |
| Cookie | GetIntCookie、GetInt32Cookie、GetInt64Cookie、GetStringCookie |
| 响应 | HTML200、JSON200、RenderJSON、RenderHTML、RenderJsonString |
取值方法都带 defaultValue,参数缺失时返回默认值而不是零值:
go
page := c.GetInt("page", 1)
size := c.GetInt("size", 20)API
| 方法 | 说明 |
|---|---|
Register(controllers ...IController) *Component | 注册 Controller |
Use(middleware ...GinHandlerFunc) | 挂载中间件 |
Static(relativePath, staticDir string) | 静态目录 |
StaticFile(relativePath, filepath string) | 静态文件 |
Engine() *gin.Engine | 取原生 gin 引擎 |
Run() / Stop() | 启动 / 停止(由组件生命周期自动调用) |
最小可运行示例见 examples/test_gin。