package znet import ( "errors" "fmt" "net" "zinx/utils" "zinx/ziface" ) // Server /* /** IServer 的接口实现,定义一个Serve 的服务器模块 */ type Server struct { //服务器名称 Name string //服务器绑定的ip版本 IPVersion string //服务器监听的ip地址 IP string //f服务器监听的端口 Port int //当前Server由用户绑定的回调router,也就是Server注册的链接对应的处理业务 MsgHandler ziface.IMsgHandler //该server 的连接管理器 ConnMgr ziface.IConnManager //该server创建之后自动调用的hook 函数 -- OnConnStart OnConnStart func(conn ziface.IConnection) //该server销毁连接之前自动调用的hook 函数 -- OnConnStop OnConnStop func(conn ziface.IConnection) } //实现IServer 接口 func (s *Server) Start() { fmt.Printf("[Zinx GlobalObject] Server Name : %s,Ip : %s,Port : %d\n", utils.GlobalObject.Name, utils.GlobalObject.Host, utils.GlobalObject.TcpPort) fmt.Printf("[Zinx GlobalObject] Version Name : %s,MaxConn : %d,MaxPackageSize : %d\n", utils.GlobalObject.Version, utils.GlobalObject.MaxConn, utils.GlobalObject.MaxPackageSize) fmt.Printf("[Start] Server Listenner at Ip :%s ,Port %d, is startring \n", s.IP, s.Port) go func() { //开启worker 消息队列几工作池 s.MsgHandler.StartWorkPool() //1.获取tcp地址 addr, err := net.ResolveTCPAddr(s.IPVersion, fmt.Sprintf("%s:%d", s.IP, s.Port)) if err != nil { fmt.Println("resplve tcp addr error :", err) } //2.监听服务器地址 listenner, err := net.ListenTCP(s.IPVersion, addr) if err != nil { fmt.Println("listen ", s.IPVersion, " error", err) } fmt.Println("start zinx server ", s.Name, "successful listenning") //3.阻塞等待客户端链接,处理客户端连接请求 var cid uint32 cid = 0 for { //如果有客户端连接,阻塞返回 conn, err := listenner.AcceptTCP() if err != nil { fmt.Println("accept error", err) continue } ////已经建立客户端连接,处理数据 //go func() { // for { // buf := make([]byte, 512) // len, err2 := conn.Read(buf) // if err2 != nil { // fmt.Println("recv buf error", err) // continue // } // // fmt.Printf("recv buf:%s,len:%d\n", string(buf[:len]), len) // //回显功能 // if _, err := conn.Write(buf[:len]); err != nil { // fmt.Println("write back buf error ", err) // continue // } // } //}() //设置最大连接个数判断,如果超过最大连接,那么关闭次新的连接 if s.ConnMgr.Len() >= utils.GlobalObject.MaxConn { //todo 给客户端响应超出最大连接数,错误包 fmt.Println("Too Many Connections MaxConn = ", utils.GlobalObject.MaxConn) conn.Close() continue } //处理新连接的业务和方法与conn 进行绑定 的到链接模块 dealConn := NewConnection(s, conn, cid, s.MsgHandler) cid++ go dealConn.Start() } }() } func CallBackToClient(conn *net.TCPConn, data []byte, cnt int) error { //回显业务 fmt.Println("[Conn Handle] CallBackToClient ... ") if _, err := conn.Write(data[:cnt]); err != nil { fmt.Println("write back buf err ", err) return errors.New("CallBackToClient error") } return nil } func (s *Server) Stop() { //将服务的资源,状态,链接信息进行停止,或回收 fmt.Println("[Stop] zinx Server name = ", s.Name) s.ConnMgr.ClearConn() } func (s *Server) Serve() { //启动server s.Start() //TODO 启动服务之后一些扩展业务 //阻塞 select {} } func (s *Server) AddRouter(msgId uint32, router ziface.IRouter) { s.MsgHandler.AddRouter(msgId, router) fmt.Println("add router successful") } // NewServer 初始化serve func NewServer() ziface.IServer { s := &Server{ Name: utils.GlobalObject.Name, IPVersion: "tcp4", IP: utils.GlobalObject.Host, Port: utils.GlobalObject.TcpPort, MsgHandler: NewMsgHandler(), ConnMgr: NewConnManager(), } return s } func (s *Server) GetConnMgr() ziface.IConnManager { return s.ConnMgr } // SetOnConnStart 注册OnConnStat 钩子函数方法 func (s *Server) SetOnConnStart(hookFunc func(connection ziface.IConnection)) { s.OnConnStart = hookFunc } // SetOnConnStop 注册OnConnStop 钩子函数方法 func (s *Server) SetOnConnStop(hookFunc func(connection ziface.IConnection)) { s.OnConnStop = hookFunc } // CallOnConnStart 调用OnConnStat 钩子函数方法 func (s *Server) CallOnConnStart(conn ziface.IConnection) { if s.OnConnStart != nil { fmt.Println("-----> CallOnConnStart() ....") s.OnConnStart(conn) } } // CallOnConnStop 调用OnConnStop 钩子函数方法 func (s *Server) CallOnConnStop(conn ziface.IConnection) { if s.OnConnStop != nil { fmt.Println("-----> CallOnConnStop() ....") s.OnConnStop(conn) } }