Commit 29b6d86fdeb4f3f61c1d0a0bcd8e562ea27d9442
1 parent
69d286a7
update plugin doc
Showing
8 changed files
with
105 additions
and
29 deletions
Show diff stats
Makefile
1 | all: gen game | 1 | all: gen game |
2 | IMGTIME := $(shell date "+%G%m%d_%H%M%S") | 2 | IMGTIME := $(shell date "+%G%m%d_%H%M%S") |
3 | -pname = plugin-$(IMGTIME).so | ||
4 | - | 3 | +pname = plugin-$(IMGTIME) |
4 | +race = -race | ||
5 | +#DEBUG = -gcflags "-l -N" | ||
6 | +DEBUG= | ||
5 | gen: | 7 | gen: |
6 | protoc -I./protos --go_out=./protos --go-grpc_out=./protos ./protos/*proto | 8 | protoc -I./protos --go_out=./protos --go-grpc_out=./protos ./protos/*proto |
7 | protoc-go-inject-tag -input=./pb/*.pb.go | 9 | protoc-go-inject-tag -input=./pb/*.pb.go |
@@ -9,20 +11,20 @@ gen: | @@ -9,20 +11,20 @@ gen: | ||
9 | test: | 11 | test: |
10 | go run cmd/test/client.go | 12 | go run cmd/test/client.go |
11 | http: | 13 | http: |
12 | - go run -race cmd/httpserver/http.go cmd/httpserver/AccountAction.go | 14 | + go run $(race) cmd/httpserver/http.go cmd/httpserver/AccountAction.go |
13 | 15 | ||
14 | game: | 16 | game: |
15 | go run -race cmd/gameserver/*.go | 17 | go run -race cmd/gameserver/*.go |
16 | build: | 18 | build: |
17 | - go build -race -o bin/account cmd/http.go | ||
18 | - go build -race -o bin/game cmd/gameserver/*.go | ||
19 | - go build -race -o bin/test cmd/test/client.go | 19 | + go build $(race) -o bin/account cmd/http.go |
20 | + go build $(race) -o bin/game cmd/gameserver/*.go | ||
21 | + go build $(race) -o bin/test cmd/test/client.go | ||
20 | regame:plugin | 22 | regame:plugin |
21 | lsof -i:8850 | grep "agent" | grep -v grep | awk '{print $$2}' | xargs -I {} kill -USR1 {} | 23 | lsof -i:8850 | grep "agent" | grep -v grep | awk '{print $$2}' | xargs -I {} kill -USR1 {} |
22 | 24 | ||
23 | plugin: | 25 | plugin: |
24 | cd bin && rm -rf ./plugin*.so && cd - | 26 | cd bin && rm -rf ./plugin*.so && cd - |
25 | - go build -race --buildmode=plugin -o bin/$(pname) cmd/gameserver/plugin/*.go | ||
26 | - cd bin && ln -s $(pname) plugin.so && cd - | 27 | + go build $(race) $(DEBUG) --buildmode=plugin -o bin/$(pname).so cmd/gameserver/plugin/*.go #--ldflags="-pluginpath=$(pname)" |
28 | + cd bin && ln -s $(pname).so plugin.so && cd - | ||
27 | 29 | ||
28 | .PHONY: all build protos test cert plugin | 30 | .PHONY: all build protos test cert plugin |
29 | \ No newline at end of file | 31 | \ No newline at end of file |
README.md
@@ -7,16 +7,15 @@ | @@ -7,16 +7,15 @@ | ||
7 | * 日志 | 7 | * 日志 |
8 | * 集群 | 8 | * 集群 |
9 | * 分布式 | 9 | * 分布式 |
10 | +* 热更 | ||
10 | 11 | ||
11 | 12 | ||
12 | -技术点 | ||
13 | -* golang 热更 | ||
14 | - | ||
15 | -组件名字 | 13 | +技术点: |
16 | * mongo | 14 | * mongo |
15 | +* redis | ||
17 | * etcd | 16 | * etcd |
18 | * proto + models 查询 | 17 | * proto + models 查询 |
19 | -* redis | 18 | +* golang plugin |
20 | 19 | ||
21 | ## 目录结构 | 20 | ## 目录结构 |
22 | ```text | 21 | ```text |
@@ -60,17 +59,20 @@ $ go get google.golang.org/grpc/cmd/protoc-gen-go-grpc | @@ -60,17 +59,20 @@ $ go get google.golang.org/grpc/cmd/protoc-gen-go-grpc | ||
60 | $ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc | 59 | $ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc |
61 | ``` | 60 | ``` |
62 | ## 文档 | 61 | ## 文档 |
63 | -[证书制作](doc/cret.md) | ||
64 | -[包组成结构](doc/proto.md) | ||
65 | - | 62 | +* [证书制作](doc/cret.md) |
63 | +* [包组成结构](doc/proto.md) | ||
64 | +* [go plugin热更的使用](doc/plugin.md) | ||
66 | 65 | ||
67 | ## Usage | 66 | ## Usage |
68 | -编译 & 运行 游戏服 & 登录服务 | 67 | +### 编译 & 运行 && 游戏服 & 登录服务 |
69 | ```shell | 68 | ```shell |
70 | -$ make account | ||
71 | $ make game | 69 | $ make game |
70 | +$ make account | ||
72 | ``` | 71 | ``` |
72 | + | ||
73 | 测试 | 73 | 测试 |
74 | ```shell | 74 | ```shell |
75 | $ make test | 75 | $ make test |
76 | -``` | ||
77 | \ No newline at end of file | 76 | \ No newline at end of file |
77 | +``` | ||
78 | + | ||
79 | +### | ||
78 | \ No newline at end of file | 80 | \ No newline at end of file |
cmd/gameserver/plugin/plugin.go
@@ -15,13 +15,13 @@ func init() { | @@ -15,13 +15,13 @@ func init() { | ||
15 | func GetActionMap() map[interface{}]interface{} { | 15 | func GetActionMap() map[interface{}]interface{} { |
16 | logger.Debug("init protocode...") | 16 | logger.Debug("init protocode...") |
17 | am := make(map[interface{}]interface{}) | 17 | am := make(map[interface{}]interface{}) |
18 | - am[uint32(pb.ProtoCode_LoginReq)] = LoginRpc | 18 | + am[uint32(pb.ProtoCode_LoginReq)] = "LoginRpc" |
19 | 19 | ||
20 | return am | 20 | return am |
21 | } | 21 | } |
22 | 22 | ||
23 | func LoginRpc(msg components.IMessage) (int32, interface{}) { | 23 | func LoginRpc(msg components.IMessage) (int32, interface{}) { |
24 | - //logger.Debug("11111111cmd: %v, msg: %s", msg.GetHeader().GetMsgID(), msg.GetData()) | 24 | + logger.Debug("11111111cmd: %v, msg: %s", msg.GetHeader().GetMsgID(), msg.GetData()) |
25 | req := pb.LoginReq{} | 25 | req := pb.LoginReq{} |
26 | if err := proto.Unmarshal(msg.GetData(), &req); err != nil { | 26 | if err := proto.Unmarshal(msg.GetData(), &req); err != nil { |
27 | logger.Error("loginRpc err: %v", err) | 27 | logger.Error("loginRpc err: %v", err) |
@@ -0,0 +1,22 @@ | @@ -0,0 +1,22 @@ | ||
1 | +package main | ||
2 | + | ||
3 | +import ( | ||
4 | + "plugin" | ||
5 | + "pro2d/common/logger" | ||
6 | + "testing" | ||
7 | +) | ||
8 | + | ||
9 | +func TestGetActionMap(t *testing.T) { | ||
10 | + p, err := plugin.Open("./bin/plugin.so") | ||
11 | + if err != nil { | ||
12 | + logger.Error("open error: ", err) | ||
13 | + return | ||
14 | + } | ||
15 | + logger.Debug("open success") | ||
16 | + symbol, err := p.Lookup("GetActionMap") | ||
17 | + if err != nil { | ||
18 | + logger.Error(err) | ||
19 | + return | ||
20 | + } | ||
21 | + logger.Debug("%v", symbol) | ||
22 | +} |
common/components/plugin.go
@@ -59,9 +59,12 @@ func (p *Plugin) GetAction(cmd uint32) interface{} { | @@ -59,9 +59,12 @@ func (p *Plugin) GetAction(cmd uint32) interface{} { | ||
59 | } | 59 | } |
60 | 60 | ||
61 | func (p *Plugin) SetActions(am map[interface{}]interface{}) { | 61 | func (p *Plugin) SetActions(am map[interface{}]interface{}) { |
62 | + p.Actions.Range(func(key, value interface{}) bool { | ||
63 | + p.Actions.Delete(key.(uint32)) | ||
64 | + return true | ||
65 | + }) | ||
62 | for k, v := range am { | 66 | for k, v := range am { |
63 | cmd := k.(uint32) | 67 | cmd := k.(uint32) |
64 | - p.Actions.Delete(cmd) | ||
65 | p.Actions.Store(cmd, v) | 68 | p.Actions.Store(cmd, v) |
66 | } | 69 | } |
67 | } | 70 | } |
common/components/server.go
@@ -115,12 +115,6 @@ func (s *Server) SetTimerCallback(cb TimerCallback) { | @@ -115,12 +115,6 @@ func (s *Server) SetTimerCallback(cb TimerCallback) { | ||
115 | } | 115 | } |
116 | 116 | ||
117 | func (s *Server) Start() error { | 117 | func (s *Server) Start() error { |
118 | - if s.plugins != nil { | ||
119 | - if err := s.plugins.LoadPlugin(); err != nil { | ||
120 | - return err | ||
121 | - } | ||
122 | - } | ||
123 | - | ||
124 | port := fmt.Sprintf(":%d", s.port) | 118 | port := fmt.Sprintf(":%d", s.port) |
125 | l, err := net.Listen("tcp", port) | 119 | l, err := net.Listen("tcp", port) |
126 | if err != nil { | 120 | if err != nil { |
conf/conf.yaml
@@ -34,7 +34,7 @@ server_game: | @@ -34,7 +34,7 @@ server_game: | ||
34 | port: 8850 | 34 | port: 8850 |
35 | pool_size: 1 | 35 | pool_size: 1 |
36 | debugport: 6061 | 36 | debugport: 6061 |
37 | - # plugin_path: "./bin/plugin.so" | 37 | + plugin_path: "./bin/plugin.so" |
38 | mongo: | 38 | mongo: |
39 | <<: *default-mongo | 39 | <<: *default-mongo |
40 | dbname: "game" | 40 | dbname: "game" |
@@ -0,0 +1,53 @@ | @@ -0,0 +1,53 @@ | ||
1 | + | ||
2 | +## 热更golang有状态服务 | ||
3 | +1. golang是有状态的 | ||
4 | +2. 数据+逻辑代码分离 | ||
5 | +3. 主要热更的是逻辑代码 | ||
6 | + | ||
7 | + | ||
8 | +## 启用插件 | ||
9 | +1. 启用插件, 配置文件 conf.yaml, 填入插件.so文件的路径 | ||
10 | +``` | ||
11 | +server_game: | ||
12 | + plugin_path: "./bin/plugin.so" | ||
13 | + mongo: | ||
14 | + <<: *default-mongo | ||
15 | + dbname: "game" | ||
16 | +``` | ||
17 | +2. 编译程序 & 插件. | ||
18 | +```shell | ||
19 | +$ make plugin | ||
20 | +``` | ||
21 | +* 程序和插件需要同一个golang的环境。 | ||
22 | +* golang对同一个插件只能加载一次。可以修改.so文件名字 + 软连接的方式来处理 | ||
23 | + | ||
24 | + | ||
25 | +## 写插件代码 | ||
26 | +插件中的代码主要是对线上程序 `协议=>逻辑` 的热更. | ||
27 | + | ||
28 | +比如我们要修改游戏服务协议号为`1`的逻辑。 则在`cmd/gameserver/plugin/plugin.go`文件中修改。 | ||
29 | +1. 在函数`GetActionMap`中增加一行 | ||
30 | +``` | ||
31 | +am[uint32(1)] = HotRpc | ||
32 | +``` | ||
33 | +2. 增加函数`HotRpc` | ||
34 | +``` | ||
35 | +func HotRpc(msg components.IMessage) (int32, interface{}) { | ||
36 | +} | ||
37 | +``` | ||
38 | + | ||
39 | +3. 编译插件 & 可以参考Makefile:plugin | ||
40 | +```Makefile | ||
41 | +IMGTIME := $(shell date "+%G%m%d_%H%M%S") | ||
42 | +pname = plugin-$(IMGTIME).so | ||
43 | +plugin: | ||
44 | + cd bin && rm -rf ./plugin*.so && cd - | ||
45 | + go build -race --buildmode=plugin -o bin/$(pname) cmd/gameserver/plugin/*.go | ||
46 | + cd bin && ln -s $(pname) plugin.so && cd - | ||
47 | +``` | ||
48 | + | ||
49 | +4. 把插件放到指定位置, 并给游戏服发送热更指令。可以参考Makefile:regame | ||
50 | +```Makefile | ||
51 | +regame:plugin | ||
52 | + lsof -i:8850 | grep "agent" | grep -v grep | awk '{print $$2}' | xargs -I {} kill -USR1 {} | ||
53 | +``` | ||
0 | \ No newline at end of file | 54 | \ No newline at end of file |