package znet import ( "fmt" "go-study/zinx/utils" "go-study/zinx/ziface" "net" ) type Server struct { // Name 服务器名称 Name string // IPVersion tcp4 or tcp6 IPVersion string // IP 服务器监听的 IP IP string // Port 服务器监听的端口 Port int // MsgHandler 该服务器的消息管理模块,用来绑定 MsgID 和对应的处理方法 MsgHandler ziface.IMsgHandle } // NewServer 创建一个服务器句柄 func NewServer() ziface.IServer { utils.ConfigInstance.Reload() return &Server{ Name: utils.ConfigInstance.Name, IPVersion: "tcp4", IP: utils.ConfigInstance.Host, Port: utils.ConfigInstance.TcpPort, MsgHandler: NewMsgHandle(), } } // Start 启动服务器 func (s *Server) Start() { fmt.Printf("[START] Server name: %s, listenner at IP: %s, Port %d, is starting\n", s.Name, s.IP, s.Port) fmt.Printf("[Zinx] Version %s, MaxConn: %d, MaxPacketSize: %d\n", utils.ConfigInstance.Version, utils.ConfigInstance.MaxConn, utils.ConfigInstance.MaxPacketSize) go func() { // 0. 启动消息队列及 worker 工作池 s.MsgHandler.StartWorkerPool() // 1. 获取一个 TCP 的 Addr addr, err := net.ResolveTCPAddr(s.IPVersion, fmt.Sprintf("%s:%d", s.IP, s.Port)) if err != nil { fmt.Println("resolve tcp addr error:", err) return } // 2. 监听服务器地址 listener, err := net.ListenTCP(s.IPVersion, addr) if err != nil { fmt.Println("listen", s.IPVersion, "err", err) return } fmt.Println("start Zinx server ", s.Name, " succ, now listening...") // TODO 应该有一个自动生成 ID 的方法 cid := uint32(0) // 3. 阻塞等待客户端连接,处理客户端连接业务(读写) for { // 3.1 阻塞等待客户端连接,AcceptTCP 会阻塞 conn, err := listener.AcceptTCP() if err != nil { fmt.Println("Accept err", err) continue } // 3.2 TODO 设置服务器最大连接数,如果超过最大连接数则关闭此新连接 // 3.3 处理该新连接请求的业务方法,此时 handler 和 conn 应该是绑定的 dealConn := NewConnection(conn, cid, s.MsgHandler) cid++ // 3.4 启动当前连接的业务处理 go dealConn.Start() } }() } // Stop 停止服务器 func (s *Server) Stop() { fmt.Println("[STOP] Zinx server, name ", s.Name) // TODO 将需要清理的连接信息或者其他信息一并停止或者清理 } // Serve 运行服务器 func (s *Server) Serve() { s.Start() // TODO 做一些启动服务器之后的额外业务 // 阻塞,否则主 Go 程退出,listener 会退出 select {} } // AddRouter 为当前服务注册一个路由方法,供客户端连接处理使用 func (s *Server) AddRouter(msgID uint32, router ziface.IRouter) { s.MsgHandler.AddRouter(msgID, router) fmt.Println("Add Router Succ!") }