From 29b6d86fdeb4f3f61c1d0a0bcd8e562ea27d9442 Mon Sep 17 00:00:00 2001 From: zqj <582132116@qq.com> Date: Mon, 21 Mar 2022 18:43:51 +0800 Subject: [PATCH] update plugin doc --- Makefile | 18 ++++++++++-------- README.md | 24 +++++++++++++----------- cmd/gameserver/plugin/plugin.go | 4 ++-- cmd/gameserver/plugin/plugin_test.go | 22 ++++++++++++++++++++++ common/components/plugin.go | 5 ++++- common/components/server.go | 6 ------ conf/conf.yaml | 2 +- doc/plugin.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 105 insertions(+), 29 deletions(-) create mode 100644 cmd/gameserver/plugin/plugin_test.go create mode 100644 doc/plugin.md diff --git a/Makefile b/Makefile index f13fe50..a75dd1a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,9 @@ all: gen game IMGTIME := $(shell date "+%G%m%d_%H%M%S") -pname = plugin-$(IMGTIME).so - +pname = plugin-$(IMGTIME) +race = -race +#DEBUG = -gcflags "-l -N" +DEBUG= gen: protoc -I./protos --go_out=./protos --go-grpc_out=./protos ./protos/*proto protoc-go-inject-tag -input=./pb/*.pb.go @@ -9,20 +11,20 @@ gen: test: go run cmd/test/client.go http: - go run -race cmd/httpserver/http.go cmd/httpserver/AccountAction.go + go run $(race) cmd/httpserver/http.go cmd/httpserver/AccountAction.go game: go run -race cmd/gameserver/*.go build: - go build -race -o bin/account cmd/http.go - go build -race -o bin/game cmd/gameserver/*.go - go build -race -o bin/test cmd/test/client.go + go build $(race) -o bin/account cmd/http.go + go build $(race) -o bin/game cmd/gameserver/*.go + go build $(race) -o bin/test cmd/test/client.go regame:plugin lsof -i:8850 | grep "agent" | grep -v grep | awk '{print $$2}' | xargs -I {} kill -USR1 {} plugin: cd bin && rm -rf ./plugin*.so && cd - - go build -race --buildmode=plugin -o bin/$(pname) cmd/gameserver/plugin/*.go - cd bin && ln -s $(pname) plugin.so && cd - + go build $(race) $(DEBUG) --buildmode=plugin -o bin/$(pname).so cmd/gameserver/plugin/*.go #--ldflags="-pluginpath=$(pname)" + cd bin && ln -s $(pname).so plugin.so && cd - .PHONY: all build protos test cert plugin \ No newline at end of file diff --git a/README.md b/README.md index ac65f00..9534f24 100644 --- a/README.md +++ b/README.md @@ -7,16 +7,15 @@ * 日志 * 集群 * 分布式 +* 热更 -技术点 -* golang 热更 - -组件名字 +技术点: * mongo +* redis * etcd * proto + models 查询 -* redis +* golang plugin ## 目录结构 ```text @@ -60,17 +59,20 @@ $ go get google.golang.org/grpc/cmd/protoc-gen-go-grpc $ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc ``` ## 文档 -[证书制作](doc/cret.md) -[包组成结构](doc/proto.md) - +* [证书制作](doc/cret.md) +* [包组成结构](doc/proto.md) +* [go plugin热更的使用](doc/plugin.md) ## Usage -编译 & 运行 游戏服 & 登录服务 +### 编译 & 运行 && 游戏服 & 登录服务 ```shell -$ make account $ make game +$ make account ``` + 测试 ```shell $ make test -``` \ No newline at end of file +``` + +### \ No newline at end of file diff --git a/cmd/gameserver/plugin/plugin.go b/cmd/gameserver/plugin/plugin.go index 775a434..e0ad9cf 100644 --- a/cmd/gameserver/plugin/plugin.go +++ b/cmd/gameserver/plugin/plugin.go @@ -15,13 +15,13 @@ func init() { func GetActionMap() map[interface{}]interface{} { logger.Debug("init protocode...") am := make(map[interface{}]interface{}) - am[uint32(pb.ProtoCode_LoginReq)] = LoginRpc + am[uint32(pb.ProtoCode_LoginReq)] = "LoginRpc" return am } func LoginRpc(msg components.IMessage) (int32, interface{}) { - //logger.Debug("11111111cmd: %v, msg: %s", msg.GetHeader().GetMsgID(), msg.GetData()) + logger.Debug("11111111cmd: %v, msg: %s", msg.GetHeader().GetMsgID(), msg.GetData()) req := pb.LoginReq{} if err := proto.Unmarshal(msg.GetData(), &req); err != nil { logger.Error("loginRpc err: %v", err) diff --git a/cmd/gameserver/plugin/plugin_test.go b/cmd/gameserver/plugin/plugin_test.go new file mode 100644 index 0000000..46ced79 --- /dev/null +++ b/cmd/gameserver/plugin/plugin_test.go @@ -0,0 +1,22 @@ +package main + +import ( + "plugin" + "pro2d/common/logger" + "testing" +) + +func TestGetActionMap(t *testing.T) { + p, err := plugin.Open("./bin/plugin.so") + if err != nil { + logger.Error("open error: ", err) + return + } + logger.Debug("open success") + symbol, err := p.Lookup("GetActionMap") + if err != nil { + logger.Error(err) + return + } + logger.Debug("%v", symbol) +} diff --git a/common/components/plugin.go b/common/components/plugin.go index 2cb657a..5802c1d 100644 --- a/common/components/plugin.go +++ b/common/components/plugin.go @@ -59,9 +59,12 @@ func (p *Plugin) GetAction(cmd uint32) interface{} { } func (p *Plugin) SetActions(am map[interface{}]interface{}) { + p.Actions.Range(func(key, value interface{}) bool { + p.Actions.Delete(key.(uint32)) + return true + }) for k, v := range am { cmd := k.(uint32) - p.Actions.Delete(cmd) p.Actions.Store(cmd, v) } } diff --git a/common/components/server.go b/common/components/server.go index ce7d6c6..610fda9 100644 --- a/common/components/server.go +++ b/common/components/server.go @@ -115,12 +115,6 @@ func (s *Server) SetTimerCallback(cb TimerCallback) { } func (s *Server) Start() error { - if s.plugins != nil { - if err := s.plugins.LoadPlugin(); err != nil { - return err - } - } - port := fmt.Sprintf(":%d", s.port) l, err := net.Listen("tcp", port) if err != nil { diff --git a/conf/conf.yaml b/conf/conf.yaml index 139c7aa..e1aeb06 100644 --- a/conf/conf.yaml +++ b/conf/conf.yaml @@ -34,7 +34,7 @@ server_game: port: 8850 pool_size: 1 debugport: 6061 - # plugin_path: "./bin/plugin.so" + plugin_path: "./bin/plugin.so" mongo: <<: *default-mongo dbname: "game" diff --git a/doc/plugin.md b/doc/plugin.md new file mode 100644 index 0000000..f16f57a --- /dev/null +++ b/doc/plugin.md @@ -0,0 +1,53 @@ + +## 热更golang有状态服务 +1. golang是有状态的 +2. 数据+逻辑代码分离 +3. 主要热更的是逻辑代码 + + +## 启用插件 +1. 启用插件, 配置文件 conf.yaml, 填入插件.so文件的路径 +``` +server_game: + plugin_path: "./bin/plugin.so" + mongo: + <<: *default-mongo + dbname: "game" +``` +2. 编译程序 & 插件. +```shell +$ make plugin +``` +* 程序和插件需要同一个golang的环境。 +* golang对同一个插件只能加载一次。可以修改.so文件名字 + 软连接的方式来处理 + + +## 写插件代码 +插件中的代码主要是对线上程序 `协议=>逻辑` 的热更. + +比如我们要修改游戏服务协议号为`1`的逻辑。 则在`cmd/gameserver/plugin/plugin.go`文件中修改。 +1. 在函数`GetActionMap`中增加一行 +``` +am[uint32(1)] = HotRpc +``` +2. 增加函数`HotRpc` +``` +func HotRpc(msg components.IMessage) (int32, interface{}) { +} +``` + +3. 编译插件 & 可以参考Makefile:plugin +```Makefile +IMGTIME := $(shell date "+%G%m%d_%H%M%S") +pname = plugin-$(IMGTIME).so +plugin: + cd bin && rm -rf ./plugin*.so && cd - + go build -race --buildmode=plugin -o bin/$(pname) cmd/gameserver/plugin/*.go + cd bin && ln -s $(pname) plugin.so && cd - +``` + +4. 把插件放到指定位置, 并给游戏服发送热更指令。可以参考Makefile:regame +```Makefile +regame:plugin + lsof -i:8850 | grep "agent" | grep -v grep | awk '{print $$2}' | xargs -I {} kill -USR1 {} +``` \ No newline at end of file -- libgit2 0.21.2