社区leaf学习笔记|03. 调试Game、Login模块收发消息

main.go 代码如下:

package main
import (
   "flag"
   "server/conf"
   "server/game"
   "server/gate"
   "server/login"
   _ "time"
   _ "FenDZ/glog-master"
   _ "github.com/dop251/goja" // JS 解析器
   "github.com/name5566/leaf"
   lconf "github.com/name5566/leaf/conf"
)
func init() {
   // 初始化 日志系统
   flag.Set("alsologtostderr", "true") // 日志写入文件的同时,输出到stderr
   flag.Set("log_dir", "./log")        // 日志文件保存目录
   flag.Set("v", "3")                  // 配置V输出的等级。
   flag.Parse()
   return
}
func main() {
   // 加载配置
   lconf.LogLevel = conf.Server.LogLevel
   lconf.LogPath = conf.Server.LogPath
   lconf.LogFlag = conf.LogFlag
   lconf.ConsolePort = conf.Server.ConsolePort
   lconf.ProfilePath = conf.Server.ProfilePath
   // 注册模块
   leaf.Run(
       game.Module,
       gate.Module,
       login.Module,
   )
}


main.go代码就不做过多讲解,如果不懂群里咨询。


本节完成以下知识点

  • 消息配置,实现不同功能对应不同的消息,防止数据传输处理换乱。

    文件:server\msg\msg.go 

package msg
import (
   "github.com/name5566/leaf/network"
   "github.com/name5566/leaf/network/json"
)
var Processorbak network.Processor
// 使用默认的 JSON 消息处理器(默认还提供了 protobuf 消息处理器)
var Processor = json.NewProcessor()
func init() {
   // 这里我们注册了一个 JSON 消息 Test
   Processor.Register(&Test{})
   // 注册登陆协议
   Processor.Register(&UserLogin{})
}
// 一个结构体定义了一个 JSON 消息的格式
// 消息名为 Test
type Test struct {
   Name string
}
// 用户登陆的协议
type UserLogin struct {
   LoginName string
   LoginPW   string
}


  • 配置路由,实现将消息Test、UserLogin分别发给Game和Login模块

    文件:server\gate\router.go 

package gate
import (
   "server/game"
   "server/login"
   "server/msg"
)
func init() {
   // 这里指定消息 Test 路由到 game 模块
   // 模块间使用 ChanRPC 通讯,消息路由也不例外
   msg.Processor.SetRouter(&msg.Test{}, game.ChanRPC)
   // 路由分发数据到login
   msg.Processor.SetRouter(&msg.UserLogin{}, login.ChanRPC)
}



  • game模块处理消息

    文件位置:server\game\internal\handler.go

package internal
import (
   "reflect"
   "server/msg"
   "github.com/name5566/leaf/gate"
   "github.com/name5566/leaf/log"
)
func init() {
   // 向当前模块(game 模块)注册 Test 消息的消息处理函数 handleTest
   handler(&msg.Test{}, handleTest)
}
// 异步处理
func handler(m interface{}, h interface{}) {
   skeleton.RegisterChanRPC(reflect.TypeOf(m), h)
}
// 消息处理
func handleTest(args []interface{}) {
   // 收到的 Test 消息
   m := args[0].(*msg.Test)
   // 消息的发送者
   a := args[1].(gate.Agent)
   // 输出收到的消息的内容
   log.Debug("hello game %v", m.Name)
   // 给发送者回应一个 Test 消息
   a.WriteMsg(&msg.Test{
       Name: "client",
   })
}



  • login模块处理消息

    文件位置:server\login\internal\handler.go

package internal
import (
   "reflect"
   "server/msg"
   "github.com/name5566/leaf/gate"
   "github.com/name5566/leaf/log"
)
func handleMsg(m interface{}, h interface{}) {
   skeleton.RegisterChanRPC(reflect.TypeOf(m), h)
}
func init() {
   // 向当前模块(login 模块)注册 Test 消息的消息处理函数 handleTest
   handleMsg(&msg.UserLogin{}, handleTest)
}
// 消息处理
func handleTest(args []interface{}) {
   // 收到的 Test 消息
   m := args[0].(*msg.UserLogin)
   // 消息的发送者
   a := args[1].(gate.Agent)
   // 1 查询数据库--判断用户是不是合法
   // 2 如果数据库返回查询正确--保存到缓存或者内存
   // 输出收到的消息的内容
   log.Debug("Test login %v", m.LoginName)
   // 给发送者回应一个 Test 消息
   a.WriteMsg(&msg.Test{
       Name: "client",
   })
}



  • TCP_模拟客户端

package main
import (
   "encoding/binary"
   "net"
)
func main() {
   conn, err := net.Dial("tcp", "127.0.0.1:8888")
   if err != nil {
       panic(err)
   }
   // Test 消息(JSON 格式)
   // 对应游戏服务器 Test 消息结构体
   data := []byte(`{
       "Test": {
           "Name": "leaf"
       }
   }`)
   // len + data
   m := make([]byte, 2+len(data))
   // 默认使用大端序
   binary.BigEndian.PutUint16(m, uint16(len(data)))
   copy(m[2:], data)
   // 发送消息
   conn.Write(m)
   if true {
       data := []byte(`{
       "UserLogin": {
           "LoginName": "leaf",
           "LoginPW" :"sss"
       }
   }`)
       // len + data
       m := make([]byte, 2+len(data))
       // 默认使用大端序
       binary.BigEndian.PutUint16(m, uint16(len(data)))
       copy(m[2:], data)
       // 发送消息
       conn.Write(m)
   }
}



  • 测试结果 如下

    社区leaf学习笔记|03. 调试Game、Login模块收发消息


上一篇:社区leaf学习笔记|01. leaf开源游戏服务器搭建


下一篇:9种分布式ID生成方式,总有一款适合你