go脚手架link源码分析
一直觉得这是个非常优秀的项目,非常精练,值得一读。
昨天下班特意画一个小时读了一遍,代码非常短,使用go做网络开发的同学可以读一下。
短小精悍,今天特写写了一篇博客介绍下。读起来特别开心。针对。
项目地址
项目的使用,从官网抄的
package main import ( "log" "net" "github.com/funny/link" "github.com/funny/link/codec" ) type AddReq struct { A, B int } type AddRsp struct { C int } type Server struct{} func main() { json := codec.Json() json.Register(AddReq{}) json.Register(AddRsp{}) listen, err := net.Listen("tcp", "") checkErr(err) server := link.NewServer(listen, json, 1024, new(Server)) go server.Serve() addr := server.Listener().Addr() clientSession, err := link.Dial(addr.Network(), addr.String(), json, 1024) checkErr(err) clientSessionLoop(clientSession) } func (*Server) HandleSession(session *link.Session) { for { req, err := session.Receive() checkErr(err) err = session.Send(&AddRsp{ req.(*AddReq).A + req.(*AddReq).B, }) checkErr(err) } } func clientSessionLoop(session *link.Session) { for i := 0; i < 10; i++ { err := session.Send(&AddReq{ i, i, }) checkErr(err) log.Printf("Send: %d + %d", i, i) rsp, err := session.Receive() checkErr(err) log.Printf("Receive: %d", rsp.(*AddRsp).C) } } func checkErr(err error) { if err != nil { log.Fatal(err) } }
项目的主体结构分析
1 Protocol 接口,主要通过接受io.ReadWriter接口参数,创建协议解析器
2 ProtocolFunc 定义函数类型,处理rw io.ReadWrite和返回Codec,err的都可以使用
3 Accept 接受tcp连接,这部分抄了net.http的包
4 Server是读Session请求的转发
type Server struct { manager *Manager //session管理器 listener net.Listener //网络连接 protocol Protocol //协议解析器 handler Handler//session处理器 sendChanSize int//发送chan的大小 }
5 manager对session进行了统一管理,还进行了分片
6 session 处理网络请求的支持同步和异步两种方式
//sessionId var globalSessionId uint64 type Session struct { id uint64 //id codec Codec //解析器 manager *Manager //管理器 sendChan chan interface{}//发送通道 recvMutex sync.Mutex //接收的锁 sendMutex sync.RWMutex//发送的锁 closeFlag int32 //关闭flag closeChan chan int//关闭的chan closeMutex sync.Mutex//关闭的锁 firstCloseCallback *closeCallback//初次关闭的回调 lastCloseCallback *closeCallback//最后关闭的回调 State interface{}//状态 }
7 协议定义实现 codec的都能被封装
//定义协议接口 type Protocol interface { NewCodec(rw io.ReadWriter) (Codec, error) } // 协议接口的实现函数 type ProtocolFunc func(rw io.ReadWriter) (Codec, error) func (pf ProtocolFunc) NewCodec(rw io.ReadWriter) (Codec, error) { return pf(rw) } //解析器接口 1 接收 2 发送 3 关闭 type Codec interface { Receive() (interface{}, error) Send(interface{}) error Close() error } //清理关闭chan的接口 type ClearSendChan interface { ClearSendChan(<-chan interface{}) }
8 channel主要对session进行一些操作
//chanel的状态 type Channel struct { mutex sync.RWMutex sessions map[KEY]*Session // channel state State interface{} }
大体执行流程是
1 创建协议
2 定义session的处理方法
3 监听请求,建立session,对session进行处理,监听请求
4 接收请求的数据通过codec去处理,处理完毕关闭session调用session回调
5 可以通过Chan发送广播之类的操作