go腳手架link源碼分析

一直以爲這是個很是優秀的項目,很是精練,值得一讀。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)
    }
}
View Code

 

項目的主體結構分析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發送廣播之類的操做

相關文章
相關標籤/搜索