zinxv0.2 简单的链接封装和业务绑定

这里我们需要实现的功能有以下


image.png

在本章中,我们需要实现的修改Server方法中的,链接处理,修改一堆代码

go func() {
        //获取一个TCP的Addr
        addr,err := net.ResolveTCPAddr(this.IPVersion,fmt.Sprintf("%s:%d",this.IP,this.Port))
        if err!=nil{
            fmt.Println("resolve tcp addr error:",err)
        }
        //监听路由的地址
        listen,err := net.ListenTCP(this.IPVersion,addr)
        if err!=nil{
            fmt.Println("Listen",this.IPVersion,"err",err)
            return
        }

        fmt.Println("start zinx server succ",this.Name,"succ,Listening..")

        var cid uint32
        cid = 0

        //阻塞的等待客户端的链接,处理业务
        for {
            conn,err := listen.AcceptTCP()
            if err!=nil {
                fmt.Println("Accept err",err)
                continue
            }

            //客户端已经建立链接,做一些业务,因为比较简单,所以就回写吧
            dealConn := NewConnection(conn,cid,CallBackToClient)
            cid++

            //启动当前业务
            go dealConn.Start()

        }
    }()

如果所示,我们需要一个定义一下我们的Connection基本接口

package ziface

import "net"

//定义链接模块的抽象层
type IConnection interface {
    //启动链接 让当前的链接业务开始工作
    Start()
    //停止链接
    Stop()
    //获取当前链接socket conn
    GetTCPConnection() *net.TCPConn
    //获取链接ID
    GetConnID() uint32
    //获取客户的TCP IP port
    RemoteAddr() net.Addr
    //发送数据,将数据发送远程的客户端
    Send(data []byte)
}

//定义一个处理业务的方法
type HandleFunc func(*net.TCPConn,[]byte,int) error

和一个实现链接消息处理的对象

package znet

import (
    "fmt"
    "net"
    "zinx/ziface"
)

/**
    链接模块
 */
type Connection struct {
    //当前链接Socket TCP
    Conn *net.TCPConn

    //链接的ID
    ConnID uint32

    //当前链接的状态
    isClosed bool

    //当前链接的处理方法
    handleAPI ziface.HandleFunc

    //退出channel
    ExitChan chan bool
}

/**
    初始化方法
 */
func NewConnection(conn *net.TCPConn,connID uint32,callback ziface.HandleFunc) *Connection {
    c:= &Connection{
        Conn:conn,
        ConnID:connID,
        handleAPI:callback,
        isClosed:false,
        ExitChan:make(chan bool,1),
    }

    return c
}

/**
    链接的读业务方法
 */
func (c *Connection) StartReader()  {
    fmt.Println("Reader Goroutine is running...")
    defer fmt.Println("c.connID=",c.ConnID," Reader is exit,remote addr is ",c.RemoteAddr().String())
    defer c.Stop()

    for   {
        //读取客户端的数据到buf中,最大512字节
        buf :=make([]byte,512)
        cnt,err:=c.Conn.Read(buf)
        if err!=nil{
            fmt.Println("recv buf err",err)
            continue
        }

        //调用当前链接的所绑定的HandleApi
        if err:= c.handleAPI(c.Conn,buf,cnt);err!=nil{
            fmt.Println("ConnID",c.ConnID," handle is error",err)
            break
        }
    }
}

//启动链接 让当前的链接业务开始工作
func (c *Connection) Start(){
    fmt.Println("Conn Start() ... ConnID = ",c.ConnID)
    //启动从当前链接的读取数据
    go c.StartReader()
    //TODO 启动从当前链接写数据的业务
}

//停止链接
func (c *Connection) Stop(){

    //如果当前链接已经关闭
    if c.isClosed == true {
        return
    }

    c.isClosed = true
    //关闭socket链接
    c.Conn.Close()
    //回收资源
    close(c.ExitChan)
}


//获取当前链接socket conn
func (c *Connection) GetTCPConnection() *net.TCPConn{
    return c.Conn
}
//获取链接ID
func (c *Connection) GetConnID() uint32{
    return c.ConnID
}
//获取客户的TCP IP port
func (c *Connection) RemoteAddr() net.Addr{
    return c.Conn.RemoteAddr()
}
//发送数据,将数据发送远程的客户端
func (c *Connection) Send(data []byte) error {
    return nil
}

最后我们需要回到Server.go 中修改成以下代码

package znet

import (
    "errors"
    "fmt"
    "net"
    "zinx/ziface"
)

// IServer的接口实现,定义一个Server的服务器模块
type Server struct {
    //服务器名称
    Name string
    //服务器ip版本
    IPVersion string
    //服务器监听ip
    IP string
    //端口
    Port int
}

func (this *Server) Start() {
    fmt.Printf("[Start] string Listenner at IP: %s,Prot %d,is start \n",this.IP,this.Port)

    //可以不阻塞
    go func() {
        //获取一个TCP的Addr
        addr,err := net.ResolveTCPAddr(this.IPVersion,fmt.Sprintf("%s:%d",this.IP,this.Port))
        if err!=nil{
            fmt.Println("resolve tcp addr error:",err)
        }
        //监听路由的地址
        listen,err := net.ListenTCP(this.IPVersion,addr)
        if err!=nil{
            fmt.Println("Listen",this.IPVersion,"err",err)
            return
        }

        fmt.Println("start zinx server succ",this.Name,"succ,Listening..")

        var cid uint32
        cid = 0

        //阻塞的等待客户端的链接,处理业务
        for {
            conn,err := listen.AcceptTCP()
            if err!=nil {
                fmt.Println("Accept err",err)
                continue
            }

            //客户端已经建立链接,做一些业务,因为比较简单,所以就回写吧
            dealConn := NewConnection(conn,cid,CallBackToClient)
            cid++

            //启动当前业务
            go dealConn.Start()

        }
    }()

}

func CallBackToClient (conn *net.TCPConn,data []byte,cnt int)  error {
    //回显的业务
    fmt.Println("[Conn Handle] CallbackToClient...")
    if _,err:=conn.Write(data[:cnt]);err!=nil{
        return  errors.New("CallBackToClient error")
    }

    return nil
}


func (this *Server) Stop() {
    //TODO 将以西服务资源,回收
}

func (this *Server) Serve() {
    //启动服务
    this.Start()

    //TODO 启动服务后做一些额外的业务功能

    //阻塞状态
    select {

    }
}

/**
    构造函数
 */
func NewServer(name string) ziface.IServer  {
    s:= &Server{
        Name:name,
        IPVersion:"tcp4",
        IP:"0.0.0.0",
        Port:8999,
    }
    return  s
}
















©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容