HTTP?
HTTP是我们很熟悉的一种应用层协议
HTTP开发
服务处理器:Handler
就是接受和响应http请求的:(要想能够接受处理http请求就得实现这个接口方法!)
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
路由【项目开发建议:第三方httprouter
路由代替默认路由】
有个Handler是专门做路由器的:(接受所有请求,并根据请求URL将请求转发给具体的Handler)
路由器可以自定义,但基本都填nil,就是默认使用http包提供的:DefaultServeMux
路由器!
我们的项目控制层就是写一个个具体的Handler!
有一个问题?
DefaultServeMux路由器要想分发请求,必须知道项目中所有小Handler!
所以:
DefaultServeMux路由器有个方法:Handle()专门将小Handler注册到路由器中!
http包中有个方法:
func Handle(pattern string, handler Handler) {
DefaultServeMux.Handle(pattern, handler)
}
但,这两个方法都不是很方便,因为要传入一个Handler,这就需要创建一个结构体,并实现Handler后实例化传入!【实质就是实现Handler中的ServeHTTP()方法】
所以出现http.HandleFunc(pattern string, handler func(ResponseWriter, *Request))
,此函数可以将传入函数包装成Handler
后注册到路由器中!
示例
- 单独线程进行监听并服务:
// 程序入口
func main(){
go httpcontroller.HttpServer(wg,httpPort)
}
- 阻塞监听并服务:
// HttpServer 开启http监听并服务
func HttpServer(wg *sync.WaitGroup,httpPort int){
// http服务结束
defer wg.Wait()
//=================== 开启侦听服务 ====================
/* 方式一:http.ListenAndServe("localhost:"+strconv.Itoa(httpPort),nil) */
/* 方式二: 方式二更灵活,更能理解实质发生了什么!方式一底层就是方式二*/
// http服务器结构体!(对http服务整体控制的对象)
server := http.Server{
Addr: "localhost:"+strconv.Itoa(httpPort),
Handler: nil,//nil采用默认服务处理器(路由器)
ReadHeaderTimeout: time.Minute,
}
defer server.Close()
/ 给默认路由器注册一个个小Handler
registerHandlers()
// 服务器开始侦听与服务(服务就是使用默认的服务处理器分配http请求!)
err := server.ListenAndServe()
if err != nil {
log.Println("http服务开启失败:",err.Error())
}
}
注册小Handler到路由器:
// registerHandlers 将一个个小Handler注册进路由器
func registerHandlers() {
// 用户注册Handler
http.HandleFunc("/user/register", usercontoller.userRegister)
// 用户登录Handler
http.HandleFunc("/user/login", usercontoller.userLogin)
}