社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
gin,beego等底层都用的是net/http模块,上篇文章中对一个基本的http请求作了分析,这篇文章就gin怎么用的http模块的流程进行梳理。
gin的github地址
来看一个基本的gin项目代码:
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "pong",})
})
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
可以看到启动流程:
(1)首先生成一个gin.Default
(2)设置路由r.GET...
(3)启动listen and serve
首先提出问题:
(1)gin是怎么使用到http的模块的?
(2)gin的路由处理流程?
通过每个流程的分析来解答:
// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default() *Engine {
debugPrintWARNINGDefault() // go版本的校验(>1.8.x),debugPrint,debug模式的时候会有相关打印
engine := New() // 生成一个Engine结构体
engine.Use(Logger(), Recovery()) // 用了Logger和Recovery两个middleware,同时也可以自己定义middleware
return engine // 返回结构体
}
关于版本的校验等信息,debug模式下的启动日志打印
func debugPrintWARNINGDefault() {
if v, e := getMinVer(runtime.Version()); e == nil && v <= ginSupportMinGoVer { // 版本的校验,不能小于1.8
debugPrint(`[WARNING] Now Gin requires Go 1.8 or later and Go 1.9 will be required soon.
`)}
debugPrint(`[WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
`)
}
func getMinVer(v string) (uint64, error) {
first := strings.IndexByte(v, '.')
last := strings.LastIndexByte(v, '.')
fmt.Println(first)
fmt.Println(last)
if first == last {
return strconv.ParseUint(v[first+1:], 10, 64)
}
return strconv.ParseUint(v[first+1:last], 10, 64)
}
middleware:
Middleware,即中间件,功能是在请求发给Handler之前对请求进行一些处理,比如验证权限。在我的实践中,我实现了一个验证JWT的Middleware,用于API的认证。
问题:Middleware在哪里被处理的呢???
https://www.jianshu.com/p/35addb4de300
https://www.cnblogs.com/yjf512/p/9670990.html
https://cloud.tencent.com/developer/article/1383810
项目代码:
func serve(opt *options.ServerOptions) {
r := api.Engine()
logger := common.Logger()
logger.Info(fmt.Sprintf("engine started, listening %s", opt.Port))
zap.NewProductionConfig()
s := &http.Server{ // http的server服务器
Addr: fmt.Sprintf(":%s", opt.Port), // 地址为eg:":8080"
Handler: r, // gin的作用只是一个handler,并无其他作用????
// ???怎么样才能作为一个handler????都实现了ServeHTTP(ResponseWriter, *Request)方法
// handler到底实现了啥???
ReadTimeout: 600 * time.Second, //每次请求读取时长(包括header和body),用ReadHeaderTimeout会更常见
WriteTimeout: 600 * time.Second, // 设置response的time out时间
}
err := s.ListenAndServe()
if err != nil {
logger.Fatal(fmt.Sprintf("err:%v", err)) // logger.Fatal会调用exit(1)
}
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!