last time: 2020年5月12日
本文基于eudore框架六主要部分App、Config、Logger、Server、Router、Context实现简化组合而来,阅读需要net/http库基础。
net/http.Server是go web主要使用的http Sever。
可以将框架分成6个主要部分App、Config、Logger、Server、Router、Context,分别对应程序主体、配置、日志、服务、路由、请求上下文六块功能。
通常App、Server、Router、Context四部分是各框架都有,例如echo、gin、beego等框架均是。
而App和Context分别代码应用程序和一次请求的主体,内置Config再使用App更加方便,而内置Logger可以避免没有iferr忽略输出error。
获取本文源码git clone https://github.com/eudore/eudore.wiki.git,切换到eudore.wiki/frame/v1目录。
先随便大概定义一下主体:
type App struct {
context.Context
context.CancelFunc
Config
Logger
Router
Server
Middlewares []MiddlewareFunc
}
type HandlerFunc func(*Context)
type MiddlewareFunc func(HandlerFunc) HandlerFunc
type Config interface {
Get(string) interface{}
Set(string, interface{})
}
type Logger interface {
Print(...interface{})
Printf(string, ...interface{})
}
type Router interface {
Match(string, string) HandlerFunc
HandleFunc(string, string, HandlerFunc)
}
type Server interface {
SetHandler(http.Handler)
ListenAndServe(string) error
}
App是框架程序的主体对象,保存程序各个对象。
需要实现一下http.Handler接口,以及封装一个Run启动App的方法。
NewApp方法是App的创建函数,Run就简单的启动一个地址的监听,ServeHTTP方法实现http.Handler接口处理请求,闭包处理一下中间件函数。
context.Context
context.Context是App整体的生命周期,在net/http.Server中,使用context.Background()为默认生命周期,在go1.13中加入了BaseContext配置可以给Serve方法设置context.Context。
在App Stop时,可以通过context.Context cannel时,关闭net/http.Server,也可以关闭基于context.Context的goroutine。
Config部分保存各项配置,实现Get/Set数据即可,最简单的使用一个map保存数据。
Logger部分执行日志输出,最简单的接口定义和最简单的实现仅实现Print方法即可,使用fmt输出日志。
Router部分根据http请求匹配对应的处理函数,然后处理请求。
MyRouter仅实现常量和通配符两种匹配功能,将method和path合并成一个字符串,如果结尾是'*'就是通配符,使用数组保存,匹配时遍历数组报错的前缀即可;如果是常量使用map保存路由路径和处理对象即可。
Router强化实现源码版本v3。
Server部分启动http Server处理http请求。
MyServer直接简单封装net/http.Server对象,允许设置Handler和启动Server端口监听。
也可以使用简化实现的http.Servergithub.com/eudore/eudore/component/server/eudore。源码版本v2。
Context是请求上下文是一次请求的主体,保存此次请求的全部信息,通常包含一次请求的读写对象,然后保存本次请求数据,提供请求的读写操作方法。
在Context实现中包含rwl(read、write、log)对象,在次演示中Context仅实现了几个方法。