之所以使用go leaf是因为其轻便,开发效率高不高,都是看个人的,好不好用,也是看个人的,咱们不予以置评,开始干活。
关于go leaf的下载
https://github.com/name5566/leaf
框架介绍
go leaf的框架介绍,网上可以搜索,这里跳过.
直接进入go leaf的使用.
障碍一:go leaf如何使用protobuf??
我这边使用的是protobuffer的3.7.0版本,
第一步:咱们在msg目录下,创建一个proto子目录,并添加一个comand.proto文件。
comand.proto
syntax = "proto3";
package go;
//数据包
message PacketData{
uint32 MainID = 1; //母指令
uint32 SubID = 2; //子指令
bytes TransData = 3; //传输数据
}
第二步:将*.proto文件转成*.go文件。
写一个批处理专门将proto目录下的文件 转成 go文件。
@echo OFF
REM '待处理的Proto文件'
@echo "-----------Proto-file------------------"
set protocpath=C:\Users\huangdi\go\bin
for /R ".\" %%i in (*.proto) do (%protocpath%\protoc -I=%~dp0 --go_out=..\go %%i
@echo "exec->file:%%i ")
REM '生成的golang文件'
@echo "------------Go-file--------------------"
for /R "..\go" %%s in (*.go) do (@echo "creating->file:%%s")
第三步:已经有了go文件,接下来就是将协议注册到protobuf的解析器当中。咱们想法独特,所以就在msg.go里做文章
package msg
import (
"github.com/golang/protobuf/proto"
"github.com/name5566/leaf/network/json"
"github.com/name5566/leaf/network/protobuf"
protoMsg "server/msg/go"
"sync"
)
// 使用默认的 JSON 消息处理器(默认还提供了 protobuf 消息处理器)
var ProcessorProto = protobuf.NewProcessor()
func init() {
//这里的注册顺序,必须,必须,必须与【客户端】一致
RegisterMessage(&protoMsg.PacketData{})
}
//对外接口 【这里的注册函数并非线程安全】
func RegisterMessage(message proto.Message) {
var wg sync.WaitGroup
wg.Add(1)
ProcessorProto.Register(message)
wg.Done()
//log.Debug("reg ID:%v",ProcessorProto.Register(message))
}
第四步,在gate/router.go里去指派需要处理的协议消息。 需要处理的协议,是指由客户端主动发起的协议。
package gate
import (
"server/login"
"server/msg"
protoMsg "server/msg/go"
)
//路由模块分发消息【模块间使用 ChanRPC 通讯,消息路由也不例外】
//注:需要解析的结构体才进行路由分派,即用客户端主动发起的
func init() {
//派给login模块进行处理
msg.ProcessorProto.SetRouter(&protoMsg.PacketData{}, login.ChanRPC) //[proto]
}
第五步:在指定的模块内处理消息。
//login/internal/handler.go
package internal
import (
"github.com/golang/protobuf/proto"
"github.com/name5566/leaf/gate"
"reflect"
. "server/base"
protoMsg "server/msg/go"
)
func init() {
// 向当前模块(login 模块)注册 Login 消息的消息处理函数 handleTest
handleMsg(&protoMsg.PacketData{}, handleMsg) //反馈--->用户信息(由客户端反馈过来的)
}
//注册模块间的通信
func handleMsg(m interface{}, h interface{}) {
skeleton.RegisterChanRPC(reflect.TypeOf(m), h)
}
//处理消息
func handleMsg(args []interface{}) {
m := args[0].(*protoMsg.PacketData)
//a := args[1].(gate.Agent)
log.Debug("msg: %v psw:%v", m.GetMainID(), m.GetSubID())
}
protobuf到此,流程走通。
障碍二:如何接受或发送字节,针对客户端。 因为go leaf在说明文档里,已经清楚说明了,自己是怎样发送protobuf的字节的。
//以go语言作为客户端
//封装消息
func packageMsg(message proto.Message) []byte{
//
data, _ := msg.ProcessorProto.Marshal(message)
//...此处可先进行数据加密
// len +id + data
m := make([]byte, 4+len(data[1]))
// 默认使用大端序
binary.BigEndian.PutUint16(m, uint16(2+len(data[1])))
//两个字节+数据
copy(m[2:], data[0])
copy(m[4:], data[1])
return m
}
第三个障碍:如何添加数据库,与数据库日志的实现(待更)。
第四个障碍:如何使得游戏多句柄,多类型(待更)。
第五个障碍:同一种类型游戏如何 统一流程(待更)。
第六个障碍:如何发家致富。如何让玩家爱上咱们的数据(待更)。
第七个障碍:如何让游戏数据处理,从此不再是个问题(待更)。
第八个障碍:如何独步天下,并与玩家共享天下(无法待更)。
第九个障碍:你大爷,老子不是孙子。从此,咱们掌握了自己的命运,并努力于人类的解放事业(无法待更)!
待更新...