go脚手架link源码分析

Posted beckbi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go脚手架link源码分析相关的知识,希望对你有一定的参考价值。

一直觉得这是个非常优秀的项目,非常精练,值得一读。

 昨天下班特意画一个小时读了一遍,代码非常短,使用go做网络开发的同学可以读一下。

短小精悍,今天特写写了一篇博客介绍下。读起来特别开心。针对。

 

项目地址

https://github.com/funny/link 

项目的使用,从官网抄的

技术图片
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

 

项目的主体结构分析

 

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发送广播之类的操作

 

以上是关于go脚手架link源码分析的主要内容,如果未能解决你的问题,请参考以下文章

Go 源码分析:http 服务源码分析

k8s client-go源码分析 informer源码分析-概要分析

go rpc 源码分析

Go Mobile 例子 audio 源码分析

Springboot源码分析系列README

区块链入门教程以太坊源码分析p2p-dial.go源码分析