使用GoLang开发游戏服务器(二)
使用GoLang开发游戏服务器(二)
连接模块的封装
将之前的服务器模块中的处理数据切片的逻辑抽离到每个连接对象中去处理
-
当前的目录结构
IConnection
type IConnection interface { Start() Stop() GetTcpConnection() *net.TCPConn GetConnectionID() int RemoteAddr() net.Addr Send(data []byte) error } type HandleFunc func(conn *net.TCPConn, buf []byte, len int) error
Connection
type Connection struct { Conn *net.TCPConn ConnID int isClosed bool handleAPI ziface.HandleFunc ExitChan chan bool } func (c *Connection) StartReader() { fmt.Println("Reader Goroutine Start...") defer fmt.Println("Reader is Exit Remote Addr is:", c.RemoteAddr().String()) defer c.Stop() for true { buf := make([]byte, 512) count, err := c.Conn.Read(buf) if err != nil { fmt.Println("buf Read Error:", err) continue } err = c.handleAPI(c.Conn, buf, count) if err != nil { fmt.Println("handleAPI Error ConnID:", c.ConnID) break } } } func (c *Connection) Start() { fmt.Println("Conn Start() ConnID:", c.ConnID) //启动读的业务 go c.StartReader() //TODO:启动写的业务 } func (c *Connection) Stop() { fmt.Println("Conn Stop() ConnID:", c.ConnID) if c.isClosed { return } c.isClosed = true c.Conn.Close() close(c.ExitChan) } func (c *Connection) GetTcpConnection() *net.TCPConn { return c.Conn } func (c *Connection) GetConnectionID() int { return c.ConnID } func (c *Connection) RemoteAddr() net.Addr { return c.Conn.RemoteAddr() } func (c *Connection) Send(data []byte) error { return nil } func NewConnection(conn *net.TCPConn, connID int, callBack_api ziface.HandleFunc) *Connection { c := &Connection{ Conn: conn, ConnID: connID, isClosed: false, handleAPI: callBack_api, ExitChan: make(chan bool, 1), } return c }
重构之前server中的代码
func (s *Server) Start() { go func() { addr, err := net.ResolveTCPAddr(s.IpVersion, fmt.Sprintf("%s:%d", s.Ip, s.Port)) if err != nil { fmt.Println("Resolve TCP Address Error", err) return } listener, err := net.ListenTCP(s.IpVersion, addr) if err != nil { fmt.Println("Listen Error", err) return } fmt.Println("Server Start !") var cID = 0 for true { conn, err := listener.AcceptTCP() if err != nil { fmt.Println("Account Error", err) continue } dealConn := NewConnection(conn, cID, CallBackToClient) cID++ dealConn.Start() } }() }