使用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()
		}
	}()
}
经验分享 程序员 微信小程序 职场和发展