diff --git a/ziface/iconnnection.go b/ziface/iconnnection.go index 5985cea..f751ca0 100644 --- a/ziface/iconnnection.go +++ b/ziface/iconnnection.go @@ -20,6 +20,4 @@ type IConnection interface { SendBuff(data []byte) error } -//定义一个统一处理链接业务的接口 -type HandFunc func(*net.TCPConn, []byte, int) error diff --git a/ziface/irequest.go b/ziface/irequest.go new file mode 100644 index 0000000..a87d505 --- /dev/null +++ b/ziface/irequest.go @@ -0,0 +1,11 @@ +package ziface + +/* + IRequest 接口: + 实际上是把客户端请求的链接信息 和 请求的数据 包装到了 Request里 +*/ +type IRequest interface{ + GetConnection() IConnection //获取请求连接信息 + GetData() []byte //获取请求消息的数据 +} + diff --git a/ziface/irouter.go b/ziface/irouter.go new file mode 100644 index 0000000..affc411 --- /dev/null +++ b/ziface/irouter.go @@ -0,0 +1,11 @@ +package ziface + +/* + 路由接口, 这里面路由是 使用框架者给该链接自定的 处理业务方法 + 路由里的IRequest 则包含用该链接的链接信息和该链接的请求数据信息 +*/ +type IRouter interface{ + PreHandle(request IRequest) //在处理conn业务之前的钩子方法 + Handle(request IRequest) //处理conn业务的方法 + PostHandle(request IRequest) //处理conn业务之后的钩子方法 +} diff --git a/ziface/iserver.go b/ziface/iserver.go index cdf1efe..4ac018d 100644 --- a/ziface/iserver.go +++ b/ziface/iserver.go @@ -8,4 +8,6 @@ type IServer interface{ Stop() //开启业务服务方法 Serve() + //路由功能:给当前服务注册一个路由业务方法,供客户端链接处理使用 + AddRouter(router IRouter) } \ No newline at end of file diff --git a/znet/connection.go b/znet/connection.go index e4e0ebd..db640dd 100644 --- a/znet/connection.go +++ b/znet/connection.go @@ -14,8 +14,8 @@ type Connection struct { //当前连接的关闭状态 isClosed bool - //该连接的处理方法api - handleAPI ziface.HandFunc + //该连接的处理方法router + Router ziface.IRouter //告知该链接已经退出/停止的channel ExitBuffChan chan bool @@ -28,12 +28,12 @@ type Connection struct { //创建连接的方法 -func NewConntion(conn *net.TCPConn, connID uint32, callback_api ziface.HandFunc) *Connection{ +func NewConntion(conn *net.TCPConn, connID uint32, router ziface.IRouter) *Connection{ c := &Connection{ Conn: conn, ConnID: connID, isClosed: false, - handleAPI: callback_api, + Router: router, ExitBuffChan: make(chan bool, 1), // SendBuffChan: make(chan []byte, 512), } @@ -49,21 +49,31 @@ func (c *Connection) StartReader() { for { //读取我们最大的数据到buf中 buf := make([]byte, 512) - cnt, err := c.Conn.Read(buf) + _, err := c.Conn.Read(buf) if err != nil { fmt.Println("recv buf err ", err) c.ExitBuffChan <- true continue } - //调用当前链接业务 - if err := c.handleAPI(c.Conn, buf, cnt); err !=nil { - fmt.Println("connID ", c.ConnID, " handle is error") - c.ExitBuffChan <- true - return + //得到当前客户端请求的Request数据 + req := Request{ + conn:c, + data:buf, } + //从路由Routers 中找到注册绑定Conn的对应Handle + go func (request ziface.IRequest) { + //执行注册的路由方法 + c.Router.PreHandle(request) + c.Router.Handle(request) + c.Router.PostHandle(request) + }(&req) + + //if err := c.handleAPI(c.Conn, buf, cnt); err !=nil { + // fmt.Println("connID ", c.ConnID, " handle is error") + // c.ExitBuffChan <- true + // return + //} } - - } //启动连接,让当前连接开始工作 @@ -101,7 +111,7 @@ func (c *Connection) Stop() { c.ExitBuffChan <- true //关闭该链接全部管道 - //close(c.ExitBuffChan) + close(c.ExitBuffChan) //close(c.SendBuffChan) } diff --git a/znet/request.go b/znet/request.go new file mode 100644 index 0000000..4d46cbf --- /dev/null +++ b/znet/request.go @@ -0,0 +1,16 @@ +package znet + +import "zinx/ziface" + +type Request struct { + conn ziface.IConnection //已经和客户端建立好的 链接 + data []byte //客户端请求的数据 +} +//获取请求连接信息 +func(r *Request) GetConnection() ziface.IConnection { + return r.conn +} +//获取请求消息的数据 +func(r *Request) GetData() []byte { + return r.data +} \ No newline at end of file diff --git a/znet/router.go b/znet/router.go new file mode 100644 index 0000000..0b88fc6 --- /dev/null +++ b/znet/router.go @@ -0,0 +1,13 @@ +package znet + +import "zinx/ziface" + +//实现router时,先嵌入这个基类,然后根据需要对这个基类的方法进行重写 +type BaseRouter struct {} + +//这里之所以BaseRouter的方法都为空, +// 是因为有的Router不希望有PreHandle或PostHandle +// 所以Router全部继承BaseRouter的好处是,不需要实现PreHandle和PostHandle也可以实例化 +func (br *BaseRouter)PreHandle(req ziface.IRequest){} +func (br *BaseRouter)Handle(req ziface.IRequest){} +func (br *BaseRouter)PostHandle(req ziface.IRequest){} diff --git a/znet/server.go b/znet/server.go index 90d53fc..4242bcd 100644 --- a/znet/server.go +++ b/znet/server.go @@ -1,7 +1,6 @@ package znet import ( - "errors" "fmt" "net" "time" @@ -18,19 +17,24 @@ type Server struct { IP string //服务绑定的端口 Port int + //当前Server由用户绑定的回调router,也就是Server注册的链接对应的处理业务 + Router ziface.IRouter } -//============== 定义当前客户端链接的handle api =========== -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") +/* + 创建一个服务器句柄 + */ +func NewServer (name string) ziface.IServer { + s:= &Server { + Name :name, + IPVersion:"tcp4", + IP:"0.0.0.0", + Port:7777, + Router: nil, } - return nil -} + return s +} //============== 实现 ziface.IServer 里的全部接口方法 ======== //开启网络服务 @@ -72,7 +76,7 @@ func (s *Server) Start() { //3.2 TODO Server.Start() 设置服务器最大连接控制,如果超过最大连接,那么则关闭此新的连接 //3.3 处理该新连接请求的 业务 方法, 此时应该有 handler 和 conn是绑定的 - dealConn := NewConntion(conn, cid, CallBackToClient) + dealConn := NewConntion(conn, cid, s.Router) cid ++ //3.4 启动当前链接的处理业务 @@ -98,17 +102,11 @@ func (s *Server) Serve() { } } +//路由功能:给当前服务注册一个路由业务方法,供客户端链接处理使用 +func (s *Server)AddRouter(router ziface.IRouter) { + s.Router = router + + fmt.Println("Add Router succ! " ) +} -/* - 创建一个服务器句柄 - */ -func NewServer (name string) ziface.IServer { - s:= &Server { - Name :name, - IPVersion:"tcp4", - IP:"0.0.0.0", - Port:7777, - } - return s -} \ No newline at end of file diff --git a/znet/server_test.go b/znet/server_test.go index 9d93e79..11f53d6 100644 --- a/znet/server_test.go +++ b/znet/server_test.go @@ -5,6 +5,7 @@ import ( "net" "testing" "time" + "zinx/ziface" ) /* @@ -23,7 +24,7 @@ import ( } for { - _, err := conn.Write([]byte("hahaha")) + _, err := conn.Write([]byte("Zinx V0.2 test")) if err !=nil { fmt.Println("write error err ", err) return @@ -42,18 +43,61 @@ import ( } } + /* //Server 模块的测试函数 func TestServer(t *testing.T) { - /* - 服务端测试 - */ + + // 服务端测试 //1 创建一个server 句柄 s s := NewServer("[zinx V0.1]") - /* - 客户端测试 - */ + // 客户端测试 + go ClientTest() + + //2 开启服务 + s.Serve() +} +*/ + +//ping test 自定义路由 +type PingRouter struct { + BaseRouter +} + +//Test PreHandle +func (this *PingRouter) PreHandle(request ziface.IRequest) { + fmt.Println("Call Router PreHandle") + _, err := request.GetConnection().GetTCPConnection().Write([]byte("before ping ....\n")) + if err !=nil { + fmt.Println("call back ping ping ping error") + } +} +//Test Handle +func (this *PingRouter) Handle(request ziface.IRequest) { + fmt.Println("Call PingRouter Handle") + _, err := request.GetConnection().GetTCPConnection().Write([]byte("ping...ping...ping\n")) + if err !=nil { + fmt.Println("call back ping ping ping error") + } +} + +//Test PostHandle +func (this *PingRouter) PostHandle(request ziface.IRequest) { + fmt.Println("Call Router PostHandle") + _, err := request.GetConnection().GetTCPConnection().Write([]byte("After ping .....\n")) + if err !=nil { + fmt.Println("call back ping ping ping error") + } +} + +func TestServerV0_3(t *testing.T){ + //创建一个server句柄 + s := NewServer("[zinx V0.3]") + + s.AddRouter(&PingRouter{}) + + // 客户端测试 go ClientTest() //2 开启服务