一直以爲這是個很是優秀的項目,很是精練,值得一讀。git
昨天下班特地畫一個小時讀了一遍,代碼很是短,使用go作網絡開發的同窗能夠讀一下。github
短小精悍,今天特寫寫了一篇博客介紹下。讀起來特別開心。針對。json
項目地址網絡
https://github.com/funny/link session
項目的使用,從官網抄的異步
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) } }
項目的主體結構分析tcp
1 Protocol 接口,主要經過接受io.ReadWriter接口參數,建立協議解析器ide
2 ProtocolFunc 定義函數類型,處理rw io.ReadWrite和返回Codec,err的均可以使用函數
3 Accept 接受tcp鏈接,這部分抄了net.http的包oop
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發送廣播之類的操做