消息管理模块开发
之前的框架只能处理一种类型的消息,只有一个路由,但是业务中往往有很多不同类型的消息要处理,所以需要框架能处理各种消息,并且让用户在外部定义
- 新增IMessageHandler.go接口文件
type IMessageHandler interface {
DoMessageHandler(request IRequest)
AddRouter(msgID uint32, router IRouter)
}
- 新增MessageHandler.go结构体文件
type MessageHandler struct {
Apis map[uint32]ziface.IRouter
}
func NewMessageHandler() *MessageHandler {
apis := make(map[uint32]ziface.IRouter)
return &MessageHandler{Apis: apis}
}
func (m *MessageHandler) DoMessageHandler(request ziface.IRequest) {
if router, ok := m.Apis[request.GetMsgID()]; ok {
router.PreHandle(request)
router.Handle(request)
router.PostHandle(request)
} else {
fmt.Println("Not Have MsgID:", request.GetMsgID())
}
}
func (m *MessageHandler) AddRouter(msgID uint32, router ziface.IRouter) {
if _, ok := m.Apis[msgID]; ok {
panic("Error MsgID Have Not Again Add MsgID:" + string(msgID))
}
m.Apis[msgID] = router
fmt.Println("Add Router success MsgID:", msgID)
}
集成消息管理模块到框架中
替换Server中原本的单一路由变量
替换Connection中的单一路由变量
测试消息管理模块
- 项目结构
- 服务端
新增一个路由来处理新的Msg
type PingRouter struct {
znet.BaseRouter
}
func (p *PingRouter) Handle(request ziface.IRequest) {
fmt.Println("服务器接收到客户端的消息,MsgID:", request.GetMsgID(), "MsgData:", string(request.GetData()))
err := request.GetConnection().SendMsg(200, []byte("ping...ping...ping..."))
if err != nil {
fmt.Println("Handle Error:", err)
return
}
}
type HelloRouter struct {
znet.BaseRouter
}
func (h *HelloRouter) Handle(request ziface.IRequest) {
fmt.Println("服务器接收到客户端的消息,MsgID:", request.GetMsgID(), "MsgData:", string(request.GetData()))
err := request.GetConnection().SendMsg(201, []byte("Hello!!!"))
if err != nil {
fmt.Println("Handle Error:", err)
return
}
}
func main() {
s := znet.NewServer("[zinxV0.5]ServerApp")
s.AddRouter(1, &PingRouter{})
s.AddRouter(2, &HelloRouter{})
s.Serve()
}
- 客户端
发送两种不同的消息
func main() {
fmt.Println("Client Start...")
time.Sleep(time.Second)
conn, err := net.Dial("tcp", "127.0.0.1:8080")
if err != nil {
fmt.Println("Client Start Error", err)
return
}
//创建子Goroutine去读取数据
go func() {
for true {
dp := znet.NewDataPack()
headData := make([]byte, dp.GetHeadLength())
_, err := io.ReadFull(conn, headData)
if err != nil {
fmt.Println(err)
return
}
msg, err := dp.UnPack(headData)
if err != nil {
fmt.Println(err)
return
}
var buffer []byte
if msg.GetMsgLength() <= 0 {
return
}
buffer = make([]byte, msg.GetMsgLength())
_, err = io.ReadFull(conn, buffer)
if err != nil {
fmt.Println(err)
return
}
msg.SetMsgData(buffer)
fmt.Println("接收服务器的消息,MsgID:", msg.GetMsgID(), "MsgData:", string(msg.GetMsgData()))
}
}()
//让主Goroutine阻塞,去写数据
for true {
dp := znet.NewDataPack()
buffer1, err := dp.Pack(znet.NewMessage(1, []byte("你好啊服务器!!! 我是消息1")))
if err != nil {
fmt.Println(err)
return
}
_, err = conn.Write(buffer1)
if err != nil {
fmt.Println(err)
return
}
//新增的消息
buffer2, err := dp.Pack(znet.NewMessage(2, []byte("你好啊服务器!!! 我是消息2")))
if err != nil {
fmt.Println(err)
return
}
_, err = conn.Write(buffer2)
if err != nil {
fmt.Println(err)
return
}
time.Sleep(time.Second)
}
}