[Go] 轻量服务器框架基础TCP连接的抽象和封装
对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 }
十年开发经验程序员,离职全心创业中,历时三年开发出的产品《唯一客服系统》
一款基于Golang+Vue开发的在线客服系统,软件著作权编号:2021SR1462600。一套可私有化部署的网站在线客服系统,编译后的二进制文件可直接使用无需搭开发环境,下载zip解压即可,仅依赖MySQL数据库,是一个开箱即用的全渠道在线客服系统,致力于帮助广大开发者/公司快速部署整合私有化客服功能。
开源地址:唯一客服(开源学习版)
官网地址:唯一客服官网