首先iserver的AddRouter()的接口要稍微改一下,增添MsgId参数
zinx/ziface/iserver.go
package ziface//定义服务器接口type IServer interface{//启动服务器方法Start()//停止服务器方法Stop()//开启业务服务方法Serve()//路由功能:给当前服务注册一个路由业务方法,供客户端链接处理使用AddRouter(msgId uint32, router IRouter)}
其次,Server类中 之前有一个Router成员 ,代表唯一的处理方法,现在应该替换成MsgHandler成员
zinx/znet/server.go
type Server struct {//服务器的名称Name string//tcp4 or otherIPVersion string//服务绑定的IP地址IP string//服务绑定的端口Port int//当前Server的消息管理模块,用来绑定MsgId和对应的处理方法msgHandler ziface.IMsgHandle}
初始化Server自然也要更正,增加msgHandler初始化
/*创建一个服务器句柄*/func NewServer () ziface.IServer {utils.GlobalObject.Reload()s:= &Server {Name :utils.GlobalObject.Name,IPVersion:"tcp4",IP:utils.GlobalObject.Host,Port:utils.GlobalObject.TcpPort,msgHandler: NewMsgHandle(), //msgHandler 初始化}return s}
然后当Server在处理conn请求业务的时候,创建conn的时候也需要把msgHandler作为参数传递给Connection对象
//...dealConn := NewConntion(conn, cid, s.msgHandler)//...
那么接下来就是Connection对象了。固然在Connection对象中应该有MsgHandler的成员,来查找消息对应的回调路由方法
zinx/znet/connection.go
type Connection struct {//当前连接的socket TCP套接字Conn *net.TCPConn//当前连接的ID 也可以称作为SessionID,ID全局唯一ConnID uint32//当前连接的关闭状态isClosed bool//消息管理MsgId和对应处理方法的消息管理模块MsgHandler ziface.IMsgHandle//告知该链接已经退出/停止的channelExitBuffChan chan bool}//创建连接的方法func NewConntion(conn *net.TCPConn, connID uint32, msgHandler ziface.IMsgHandle) *Connection{c := &Connection{Conn: conn,ConnID: connID,isClosed: false,MsgHandler: msgHandler,ExitBuffChan: make(chan bool, 1),}return c}
最后,在conn已经拆包之后,需要调用路由业务的时候,我们只需要让conn调用MsgHandler中的DoMsgHander()方法就好了
zinx/znet/connection.go
func (c *Connection) StartReader() {fmt.Println("[Reader Goroutine is running]")defer fmt.Println(c.RemoteAddr().String(), "[conn Reader exit!]")defer c.Stop()for {// 创建拆包解包的对象dp := NewDataPack()//读取客户端的Msg headheadData := make([]byte, dp.GetHeadLen())if _, err := io.ReadFull(c.GetTCPConnection(), headData); err != nil {fmt.Println("read msg head error ", err)break}//拆包,得到msgid 和 datalen 放在msg中msg , err := dp.Unpack(headData)if err != nil {fmt.Println("unpack error ", err)break}//根据 dataLen 读取 data,放在msg.Data中var data []byteif msg.GetDataLen() > 0 {data = make([]byte, msg.GetDataLen())if _, err := io.ReadFull(c.GetTCPConnection(), data); err != nil {fmt.Println("read msg data error ", err)continue}}msg.SetData(data)//得到当前客户端请求的Request数据req := Request{conn:c,msg:msg,}//从绑定好的消息和对应的处理方法中执行对应的Handle方法go c.MsgHandler.DoMsgHandler(&req)}}
好了,大功告成,我们来测试一下Zinx的多路由设置功能吧。
