从零实现gin day01

前言

刚开始学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...

相关推荐
无限大64 小时前
计算机十万个为什么--数据库索引
后端
学历真的很重要5 小时前
VsCode+Roo Code+Gemini 2.5 Pro+Gemini Balance AI辅助编程环境搭建(理论上通过多个Api Key负载均衡达到无限免费Gemini 2.5 Pro)
前端·人工智能·vscode·后端·语言模型·负载均衡·ai编程
+VX:Fegn08956 小时前
计算机毕业设计|基于springboot + vue心理健康管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
狂炫冰美式7 小时前
不谈技术,搞点文化 🧀 —— 从复活一句明代残诗破局产品迭代
前端·人工智能·后端
databook8 小时前
数据会说谎?三大推断方法帮你“审问”数据真相
后端·python·数据分析
代码栈上的思考8 小时前
深入解析Spring IoC核心与关键注解
java·后端·spring
expect7g9 小时前
Paimon源码解读 -- Compaction-2.KeyValueFileWriterFactory
大数据·后端·flink
小灰灰搞电子9 小时前
Rust 动态分发(dyn Trait)详解
开发语言·后端·rust
码事漫谈10 小时前
深入剖析进程、线程与虚拟内存
后端
码事漫谈10 小时前
MFC核心架构深度解析
后端