前言
刚开始学go想着不能一直输入,得有点输出才能记得住学的东西,故决定写一些学习笔记来记录自己的学习历程.
知识点
- 使用go开启TCP服务
- 使用go发送http请求
- 实现TCP监听回调服务
http请求封装
怎么用go开启TCP服务
go
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
writer.Write([]byte(fmt.Sprintf("hello %s\n", "cc")))
})
log.Fatal(http.ListenAndServe(":7999", nil))
}
http.HandleFunc
添加一个路由,添加了路由我们怎么去监听这个路由是否正确呢?http.ListenAndServe
中的第二个参数就派上用场了,从源码中可以看到,在开启TCP监听端口之后会回调一个handler requests
这个Handler
是一个接口,里面有一个ServeHTTP
方法,所以只要实现了这个方法的都可以作为参数传给ListenAndServe
监听源码
go
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
// ListenAndServe listens on the TCP network address addr and then calls
// Serve with handler to handle requests on incoming connections.
// Accepted connections are configured to enable TCP keep-alives.
// ListenAndServe always returns a non-nil error.
func ListenAndServe(addr string, handler Handler) error {
server := &Server{Addr: addr, Handler: handler}
return server.ListenAndServe()
}
实现
go
package main
import (
"fmt"
"net/http"
)
type Engine struct {
}
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
if path == "/" {
fmt.Fprint(w, "index")
} else if path == "/hello" {
fmt.Fprint(w, "hello world")
} else {
fmt.Fprint(w, "404")
}
}
那么main函数中的ListenAndServe
就可以直接使用这个作为回调方法传入.
go
func main() {
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
writer.Write([]byte(fmt.Sprintf("hello %s\n", "cc")))
})
e := new(Engine)
log.Fatal(http.ListenAndServe(":7999", e))
}
我们使用postman进行测试,都出现了我们预期的结果,但是在http.HandleFunc
中写的匿名函数并没有执行,要想这个匿名函数执行就要把其放到ServeHTTP
中去.所以我们可以进一步改造.
给Engine添加router,封装Post,Get,Run方法
go
package main
import (
"fmt"
"net/http"
)
type HandleFunc http.HandlerFunc
type Engine struct {
router map[string]HandleFunc
}
func newEngine() *Engine {
return &Engine{router: make(map[string]HandleFunc)}
}
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
key := r.Method + "-" + r.URL.Path
if h, ok := e.router[key]; ok {
h(w, r)
} else {
w.WriteHeader(http.StatusNotFound)
fmt.Fprint(w, "404")
}
}
func (e *Engine) AddRouter(method string, path string, handle HandleFunc) {
key := method + "-" + path
e.router[key] = handle
}
func (e *Engine) Post(path string, handle HandleFunc) {
e.AddRouter("POST", path, handle)
}
func (e *Engine) Get(path string, handle HandleFunc) {
e.AddRouter("GET", path, handle)
}
func (e *Engine) Run(addr string) (err error) {
return http.ListenAndServe(addr, e)
}
我们给Engine
添加了一个router变量,类型为map[string]HandleFunc
这样就能通过key找到其对应的HandleFunc
方法,从而执行.
总结
本章我们完成了TCP
服务监听的封装,并能通过Post
,Get
添加路由请求,并且能对不存在的路由进行提示.
更多详情连接:geektutu.com/post/gee.ht...