[Go] 轻量服务器框架基础TCP连接的抽象和封装

  • 2019 年 12 月 19 日
  • 筆記

对tcp连接部分以及与连接绑定的业务部分进行抽象和封装

主要是对连接的开启关闭和读写进行封装,抽象出接口,使用回调进行具体业务的绑定

zinterface/iconnection.go

package zinterface    import "net"    type IConnection interface{      Start()      Stop()      GetConnId() uint32      IsClosed() bool      Send(data []byte,len int) error      GetRemoteAddr() net.Addr      GetConn() *net.TCPConn  }  type HandleFunc func (*net.TCPConn,[]byte,int) error

znet/connection.go

package znet    import (      "log"      "net"      "zinx/zinterface"  )    type Connection struct {      ConnId     uint32      Conn       *net.TCPConn      Closed     bool      RemoteAddr net.Addr      ExitChan   chan bool      HandleAPI  zinterface.HandleFunc  }    func NewConnection(connid uint32, conn *net.TCPConn, callback zinterface.HandleFunc) zinterface.IConnection {      c := &Connection{          ConnId:    connid,          Conn:      conn,          Closed:    false,          ExitChan:  make(chan bool, 1),          HandleAPI: callback,      }      return c  }  func (c *Connection) StartRead() {      defer c.Stop()      for {          b := make([]byte, 512)          len, err := c.Conn.Read(b)          if err != nil {              log.Println("read tcp err ", err)              break          }          log.Printf("recv from client %s,len=%d,connid=%d", b, len,c.ConnId)            if err:=c.HandleAPI(c.Conn,b,len);err!=nil{              log.Println("c.handleAPI err ",err)              break          }        }  }  func (c *Connection) Start() {      go c.StartRead()  }  func (c *Connection) Stop() {      if c.Closed {          return      }      c.Closed = true      c.Conn.Close()      close(c.ExitChan)  }  func (c *Connection) GetConnId() uint32 {      return c.ConnId  }    func (c *Connection) Send(data []byte, len int) error {      return nil  }  func (c *Connection) GetRemoteAddr() net.Addr {      return c.Conn.RemoteAddr()  }  func (c *Connection) GetConn() *net.TCPConn {      return c.Conn  }  func (c *Connection) IsClosed() bool {      return c.Closed  }

znet/server.go

package znet    import (      "fmt"      "errors"      "log"      "net"      "zinx/zinterface"  )    type Server struct {      Name      string      IP        string      IPversion string      Port      int  }  func Callbackapi(conn *net.TCPConn,readData []byte,len int) error{      if _, err := conn.Write(readData[:len]); err != nil {          log.Println("write tcp err ", err)          return errors.New("write tcp err")      }      log.Println("callback write...")      return nil  }  func (s *Server) Start() {      log.Printf("%s %s:%d start...n", s.Name, s.IP, s.Port)      go func() {          addr, err := net.ResolveTCPAddr(s.IPversion, fmt.Sprintf("%s:%d", s.IP, s.Port))          if err != nil {              log.Println("resolve tcp addr err ", err)              return          }          listener, err := net.ListenTCP(s.IPversion, addr)          if err != nil {              log.Println("listen tcp err ", err)              return          }          var connid uint32          connid=0          for {              conn, err := listener.AcceptTCP()              if err != nil {                  log.Println("accept tcp err ", err)                  continue              }              dealConn:=NewConnection(connid,conn,Callbackapi)              go dealConn.Start()              connid++          }      }()    }  func (s *Server) Stop() {    }  func (s *Server) Server() {      s.Start()      select {}  }  func NewServer(name string) zinterface.IServer {      s := &Server{          Name:      name,          IP:        "0.0.0.0",          IPversion: "tcp4",          Port:      8999,      }      return s  }