zinx/znet/server.go

189 lines
4.7 KiB
Go

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)
}
}