189 lines
4.7 KiB
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)
|
|
}
|
|
}
|