Browse Source

Zinx-v0.3 集成简单的路由功能

master
aceld 6 years ago
parent
commit
9e81d90924
  1. 2
      ziface/iconnnection.go
  2. 11
      ziface/irequest.go
  3. 11
      ziface/irouter.go
  4. 2
      ziface/iserver.go
  5. 36
      znet/connection.go
  6. 16
      znet/request.go
  7. 13
      znet/router.go
  8. 42
      znet/server.go
  9. 56
      znet/server_test.go

2
ziface/iconnnection.go

@ -20,6 +20,4 @@ type IConnection interface {
SendBuff(data []byte) error
}
//定义一个统一处理链接业务的接口
type HandFunc func(*net.TCPConn, []byte, int) error

11
ziface/irequest.go

@ -0,0 +1,11 @@
package ziface
/*
IRequest 接口
实际上是把客户端请求的链接信息 请求的数据 包装到了 Request里
*/
type IRequest interface{
GetConnection() IConnection //获取请求连接信息
GetData() []byte //获取请求消息的数据
}

11
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业务之后的钩子方法
}

2
ziface/iserver.go

@ -8,4 +8,6 @@ type IServer interface{
Stop()
//开启业务服务方法
Serve()
//路由功能:给当前服务注册一个路由业务方法,供客户端链接处理使用
AddRouter(router IRouter)
}

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

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

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

42
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")
}
return nil
/*
创建一个服务器句柄
*/
func NewServer (name string) ziface.IServer {
s:= &Server {
Name :name,
IPVersion:"tcp4",
IP:"0.0.0.0",
Port:7777,
Router: 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
/*
创建一个服务器句柄
*/
func NewServer (name string) ziface.IServer {
s:= &Server {
Name :name,
IPVersion:"tcp4",
IP:"0.0.0.0",
Port:7777,
fmt.Println("Add Router succ! " )
}
return s
}

56
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 开启服务

Loading…
Cancel
Save