Commit 77f5eec7ee525597a19cda7029bf4a512f3ac8c0
1 parent
9a9d092e
plugin 插件热更 接口
Showing
12 changed files
with
239 additions
and
124 deletions
Show diff stats
Makefile
@@ -11,18 +11,18 @@ test: | @@ -11,18 +11,18 @@ test: | ||
11 | http: | 11 | http: |
12 | go run -race cmd/httpserver/http.go cmd/httpserver/AccountAction.go | 12 | go run -race cmd/httpserver/http.go cmd/httpserver/AccountAction.go |
13 | 13 | ||
14 | -game: | 14 | +game:plugin |
15 | go run -race cmd/gameserver/*.go | 15 | go run -race cmd/gameserver/*.go |
16 | build: | 16 | build: |
17 | go build -race -o bin/account cmd/http.go | 17 | go build -race -o bin/account cmd/http.go |
18 | go build -race -o bin/game cmd/gameserver/*.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/test cmd/test/client.go |
20 | regame:plugin | 20 | regame:plugin |
21 | - lsof -i:8849 | grep "game" | grep -v grep | awk '{print $$2}' | xargs -I {} kill -USR1 {} | 21 | + lsof -i:8850 | grep "agent" | grep -v grep | awk '{print $$2}' | xargs -I {} kill -USR1 {} |
22 | 22 | ||
23 | plugin: | 23 | plugin: |
24 | - #go build -ldflags -pluginpath="plugin/hot-1" --buildmode=plugin -o bin/plugin.so src/plugin/*.go | ||
25 | - go build --buildmode=plugin -o bin/$(pname) src/plugin/*.go | ||
26 | - cd bin && rm -rf plugin.so && ln -s $(pname) plugin.so && cd - | 24 | + 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 | 27 | ||
28 | .PHONY: all build protos test cert plugin | 28 | .PHONY: all build protos test cert plugin |
29 | \ No newline at end of file | 29 | \ No newline at end of file |
cmd/gameserver/agent.go
1 | package main | 1 | package main |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | - "fmt" | ||
5 | "github.com/golang/protobuf/proto" | 4 | "github.com/golang/protobuf/proto" |
6 | "math" | 5 | "math" |
7 | "pro2d/common" | 6 | "pro2d/common" |
8 | "pro2d/common/components" | 7 | "pro2d/common/components" |
9 | "pro2d/models" | 8 | "pro2d/models" |
10 | - "pro2d/pb" | ||
11 | "pro2d/utils" | 9 | "pro2d/utils" |
12 | "pro2d/utils/logger" | 10 | "pro2d/utils/logger" |
13 | "sync/atomic" | 11 | "sync/atomic" |
@@ -45,24 +43,30 @@ func (c *Agent) OnConnection(conn components.IConnection) { | @@ -45,24 +43,30 @@ func (c *Agent) OnConnection(conn components.IConnection) { | ||
45 | 43 | ||
46 | func (c *Agent) OnMessage(msg components.IMessage) { | 44 | func (c *Agent) OnMessage(msg components.IMessage) { |
47 | atomic.StoreInt64(&c.lastHeartCheckTime, utils.Timex()) | 45 | atomic.StoreInt64(&c.lastHeartCheckTime, utils.Timex()) |
48 | - if md, ok := components.ActionMap[pb.ProtoCode(msg.GetHeader().GetMsgID())]; ok { | ||
49 | - logger.Debug("protocode handler: %d", msg.GetHeader().GetMsgID()) | ||
50 | - errCode, protomsg := md(msg) | ||
51 | - rsp, err := proto.Marshal(protomsg) | ||
52 | - fmt.Printf("errCode: %d, protomsg:%v\n", errCode, protomsg) | ||
53 | - if err != nil { | ||
54 | - conn := c.Server.GetIConnection(msg.GetSessId()) | ||
55 | - if conn != nil { | ||
56 | - conn.Send(-100, msg.GetHeader().GetMsgID(), nil) | ||
57 | - } | ||
58 | - return | ||
59 | - } | 46 | + md := c.Server.GetPlugin().GetAction(msg.GetHeader().GetMsgID()) |
47 | + if md == nil { | ||
48 | + logger.Debug("cmd: %d, md is nil", msg.GetHeader().GetMsgID()) | ||
49 | + return | ||
50 | + } | ||
51 | + | ||
52 | + logger.Debug("protocode handler: %d", msg.GetHeader().GetMsgID()) | ||
53 | + //fmt.Printf("errCode: %d, protomsg:%v\n", errCode, protomsg) | ||
54 | + | ||
55 | + f := md.(func (conn components.IConnection, msg components.IMessage) (int32, interface{})) | ||
56 | + errCode, protomsg := f(c, msg) | ||
57 | + rsp, err := proto.Marshal(protomsg.(proto.Message)) | ||
58 | + if err != nil { | ||
60 | conn := c.Server.GetIConnection(msg.GetSessId()) | 59 | conn := c.Server.GetIConnection(msg.GetSessId()) |
61 | if conn != nil { | 60 | if conn != nil { |
62 | - conn.Send(errCode, msg.GetHeader().GetMsgID(), rsp) | 61 | + conn.Send(-100, msg.GetHeader().GetMsgID(), nil) |
63 | } | 62 | } |
64 | return | 63 | return |
65 | } | 64 | } |
65 | + conn := c.Server.GetIConnection(msg.GetSessId()) | ||
66 | + if conn != nil { | ||
67 | + conn.Send(errCode, msg.GetHeader().GetMsgID(), rsp) | ||
68 | + } | ||
69 | + return | ||
66 | logger.Error("protocode not handler: %d", msg.GetHeader().GetMsgID()) | 70 | logger.Error("protocode not handler: %d", msg.GetHeader().GetMsgID()) |
67 | } | 71 | } |
68 | 72 |
cmd/gameserver/game.go
@@ -10,7 +10,7 @@ import ( | @@ -10,7 +10,7 @@ import ( | ||
10 | "pro2d/common/components" | 10 | "pro2d/common/components" |
11 | "pro2d/conf" | 11 | "pro2d/conf" |
12 | "pro2d/models" | 12 | "pro2d/models" |
13 | - _ "pro2d/plugin" | 13 | + //_ "pro2d/cmd/gameserver/plugin" |
14 | "pro2d/utils/db" | 14 | "pro2d/utils/db" |
15 | "pro2d/utils/etcd" | 15 | "pro2d/utils/etcd" |
16 | "pro2d/utils/logger" | 16 | "pro2d/utils/logger" |
@@ -27,13 +27,20 @@ type GameServer struct { | @@ -27,13 +27,20 @@ type GameServer struct { | ||
27 | 27 | ||
28 | func NewGameServer(sconf *conf.SConf) (*GameServer, error) { | 28 | func NewGameServer(sconf *conf.SConf) (*GameServer, error) { |
29 | s := &GameServer{ | 29 | s := &GameServer{ |
30 | - IServer: components.NewServer(sconf.Port, conf.GlobalConf.GameConf.PluginPath, components.NewPBSplitter()), | ||
31 | Agents: new(sync.Map), | 30 | Agents: new(sync.Map), |
32 | } | 31 | } |
33 | - s.SetConnectionCallback(s.OnConnection) | ||
34 | - s.SetMessageCallback(s.OnMessage) | ||
35 | - s.SetCloseCallback(s.OnClose) | ||
36 | - s.SetTimerCallback(s.OnTimer) | 32 | + |
33 | + options := []components.Option{ | ||
34 | + components.WithPlugin(components.NewPlugin(sconf.PluginPath)), | ||
35 | + components.WithSplitter(components.NewPBSplitter()), | ||
36 | + components.WithConnCbk(s.OnConnection), | ||
37 | + components.WithMsgCbk(s.OnMessage), | ||
38 | + components.WithCloseCbk(s.OnClose), | ||
39 | + components.WithTimerCbk(s.OnTimer), | ||
40 | + } | ||
41 | + | ||
42 | + iserver := components.NewServer(sconf.Port, options...) | ||
43 | + s.IServer = iserver | ||
37 | 44 | ||
38 | //mongo 初始化 | 45 | //mongo 初始化 |
39 | db.MongoDatabase = db.MongoClient.Database(sconf.DBName) | 46 | db.MongoDatabase = db.MongoClient.Database(sconf.DBName) |
@@ -120,7 +127,10 @@ func main() { | @@ -120,7 +127,10 @@ func main() { | ||
120 | return | 127 | return |
121 | case u := <-userChan: | 128 | case u := <-userChan: |
122 | logger.Debug("userChan .. %v",u.String()) | 129 | logger.Debug("userChan .. %v",u.String()) |
123 | - //s.LoadPlugin() | 130 | + e := s.IServer.GetPlugin().LoadPlugin() |
131 | + if e != nil { | ||
132 | + logger.Error("err: ", e.Error()) | ||
133 | + } | ||
124 | } | 134 | } |
125 | } | 135 | } |
126 | } | 136 | } |
plugin/RolePlugin.go renamed to cmd/gameserver/plugin/RolePlugin.go
1 | -package plugin | 1 | +package main |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "github.com/golang/protobuf/proto" | 4 | "github.com/golang/protobuf/proto" |
@@ -9,12 +9,12 @@ import ( | @@ -9,12 +9,12 @@ import ( | ||
9 | "pro2d/utils/logger" | 9 | "pro2d/utils/logger" |
10 | ) | 10 | ) |
11 | 11 | ||
12 | -func HeartRpc(msg components.IMessage) (int32, proto.Message) { | 12 | +func HeartRpc(msg components.IMessage) (int32, interface{}) { |
13 | //msg.Conn.SetLastHeartCheckTime() | 13 | //msg.Conn.SetLastHeartCheckTime() |
14 | return 0, nil | 14 | return 0, nil |
15 | } | 15 | } |
16 | 16 | ||
17 | -func CreateRpc(msg components.IMessage) (int32, proto.Message) { | 17 | +func CreateRpc(msg components.IMessage) (int32, interface{}) { |
18 | req := pb.CreateReq{} | 18 | req := pb.CreateReq{} |
19 | if err := proto.Unmarshal(msg.GetData(), &req); err != nil { | 19 | if err := proto.Unmarshal(msg.GetData(), &req); err != nil { |
20 | logger.Error("CreateRpc err: %v", err) | 20 | logger.Error("CreateRpc err: %v", err) |
@@ -34,8 +34,8 @@ func CreateRpc(msg components.IMessage) (int32, proto.Message) { | @@ -34,8 +34,8 @@ func CreateRpc(msg components.IMessage) (int32, proto.Message) { | ||
34 | return 0, nil | 34 | return 0, nil |
35 | } | 35 | } |
36 | 36 | ||
37 | -func LoginRpc(msg components.IMessage) (int32, proto.Message) { | ||
38 | - //logger.Debug("cmd: %v, msg: %s", msg.PBHead.Cmd, msg.Body) | 37 | +func LoginRpc(msg components.IMessage) (int32, interface{}) { |
38 | + //logger.Debug("11111111cmd: %v, msg: %s", msg.GetHeader().GetMsgID(), msg.GetData()) | ||
39 | req := pb.LoginReq{} | 39 | req := pb.LoginReq{} |
40 | if err := proto.Unmarshal(msg.GetData(), &req); err != nil { | 40 | if err := proto.Unmarshal(msg.GetData(), &req); err != nil { |
41 | logger.Error("loginRpc err: %v", err) | 41 | logger.Error("loginRpc err: %v", err) |
@@ -48,7 +48,6 @@ func LoginRpc(msg components.IMessage) (int32, proto.Message) { | @@ -48,7 +48,6 @@ func LoginRpc(msg components.IMessage) (int32, proto.Message) { | ||
48 | } | 48 | } |
49 | role.SetProperty("Device", req.Device) | 49 | role.SetProperty("Device", req.Device) |
50 | 50 | ||
51 | - | ||
52 | return 0, &pb.RoleRsp{ | 51 | return 0, &pb.RoleRsp{ |
53 | Role: role.Role, | 52 | Role: role.Role, |
54 | Hero: role.GetAllHero(), | 53 | Hero: role.GetAllHero(), |
@@ -0,0 +1,16 @@ | @@ -0,0 +1,16 @@ | ||
1 | +package main | ||
2 | + | ||
3 | +import ( | ||
4 | + "pro2d/pb" | ||
5 | + "pro2d/utils/logger" | ||
6 | +) | ||
7 | + | ||
8 | +func GetActionMap() map[interface{}]interface{} { | ||
9 | + logger.Debug("init protocode...") | ||
10 | + am := make(map[interface{}]interface{}) | ||
11 | + am[pb.ProtoCode_HeartReq] = HeartRpc | ||
12 | + am[pb.ProtoCode_LoginReq] = LoginRpc | ||
13 | + am[pb.ProtoCode_CreateReq] = CreateRpc | ||
14 | + | ||
15 | + return am | ||
16 | +} | ||
0 | \ No newline at end of file | 17 | \ No newline at end of file |
cmd/httpserver/http.go
@@ -23,7 +23,7 @@ func NewAccountServer(version string, port ...string) *AccountServer { | @@ -23,7 +23,7 @@ func NewAccountServer(version string, port ...string) *AccountServer { | ||
23 | return &AccountServer{IHttp: components.NewHttpServer(version, port...)} | 23 | return &AccountServer{IHttp: components.NewHttpServer(version, port...)} |
24 | } | 24 | } |
25 | 25 | ||
26 | -func (s *AccountServer) Start() error { | 26 | +func (s *AccountServer) Init() error { |
27 | //mongo 初始化 | 27 | //mongo 初始化 |
28 | db.MongoDatabase = db.MongoClient.Database(conf.GlobalConf.AccountConf.DBName) | 28 | db.MongoDatabase = db.MongoClient.Database(conf.GlobalConf.AccountConf.DBName) |
29 | models.InitAccountServerModels() | 29 | models.InitAccountServerModels() |
@@ -35,6 +35,13 @@ func (s *AccountServer) Start() error { | @@ -35,6 +35,13 @@ func (s *AccountServer) Start() error { | ||
35 | return err | 35 | return err |
36 | } | 36 | } |
37 | s.EtcdClient.PutWithLeasePrefix(conf.GlobalConf.AccountConf.Name, conf.GlobalConf.AccountConf.ID, fmt.Sprintf("%s:%d", conf.GlobalConf.AccountConf.IP, conf.GlobalConf.AccountConf.Port), 5) | 37 | s.EtcdClient.PutWithLeasePrefix(conf.GlobalConf.AccountConf.Name, conf.GlobalConf.AccountConf.ID, fmt.Sprintf("%s:%d", conf.GlobalConf.AccountConf.IP, conf.GlobalConf.AccountConf.Port), 5) |
38 | + return nil | ||
39 | +} | ||
40 | + | ||
41 | +func (s *AccountServer) Start() error { | ||
42 | + if err := s.Init(); err != nil { | ||
43 | + return err | ||
44 | + } | ||
38 | 45 | ||
39 | return s.IHttp.Start() | 46 | return s.IHttp.Start() |
40 | } | 47 | } |
common/components/conn.go
@@ -74,6 +74,47 @@ func (c *Connection) SetTimerCallback(cb TimerCallback) { | @@ -74,6 +74,47 @@ func (c *Connection) SetTimerCallback(cb TimerCallback) { | ||
74 | c.timerCallback = cb | 74 | c.timerCallback = cb |
75 | } | 75 | } |
76 | 76 | ||
77 | +func (c *Connection) Start() { | ||
78 | + go c.write() | ||
79 | + go c.read() | ||
80 | + go c.listen() | ||
81 | + | ||
82 | + c.Status = 1 | ||
83 | + c.connectionCallback(c) | ||
84 | + c.handleTimeOut() | ||
85 | +} | ||
86 | + | ||
87 | +func (c *Connection) Stop() { | ||
88 | + logger.Debug("ID: %d close", c.Id) | ||
89 | + closed := atomic.LoadUint32(&c.Status) | ||
90 | + if closed == 0 { | ||
91 | + return | ||
92 | + } | ||
93 | + atomic.StoreUint32(&c.Status, 0) | ||
94 | + | ||
95 | + close(c.WBuffer) | ||
96 | + close(c.Quit) | ||
97 | + c.Conn.Close() | ||
98 | + c.closeCallback(c) | ||
99 | +} | ||
100 | + | ||
101 | +func (c *Connection) Send(errCode int32, cmd uint32, data []byte) error{ | ||
102 | + buf, err := c.Server.GetSplitter().Pack(cmd, data, errCode, 0) | ||
103 | + if err != nil { | ||
104 | + return err | ||
105 | + } | ||
106 | + | ||
107 | + sendTimeout := time.NewTimer(5 * time.Millisecond) | ||
108 | + defer sendTimeout.Stop() | ||
109 | + // 发送超时 | ||
110 | + select { | ||
111 | + case <-sendTimeout.C: | ||
112 | + return fmt.Errorf("send buff msg timeout") | ||
113 | + case c.WBuffer <- buf: | ||
114 | + return nil | ||
115 | + } | ||
116 | +} | ||
117 | + | ||
77 | func (c *Connection) defaultConnectionCallback(conn IConnection) { | 118 | func (c *Connection) defaultConnectionCallback(conn IConnection) { |
78 | } | 119 | } |
79 | 120 | ||
@@ -124,6 +165,7 @@ func (c *Connection) read() { | @@ -124,6 +165,7 @@ func (c *Connection) read() { | ||
124 | } | 165 | } |
125 | } | 166 | } |
126 | 167 | ||
168 | +//此设计目的是为了让网络数据与定时器处理都在一条协程里处理。不想加锁。。。 | ||
127 | func (c *Connection) listen(){ | 169 | func (c *Connection) listen(){ |
128 | defer c.Stop() | 170 | defer c.Stop() |
129 | 171 | ||
@@ -139,7 +181,6 @@ func (c *Connection) listen(){ | @@ -139,7 +181,6 @@ func (c *Connection) listen(){ | ||
139 | } | 181 | } |
140 | } | 182 | } |
141 | 183 | ||
142 | - | ||
143 | func (c *Connection) handleTimeOut() { | 184 | func (c *Connection) handleTimeOut() { |
144 | c.timerFunc <- func() { | 185 | c.timerFunc <- func() { |
145 | c.timerCallback(c) | 186 | c.timerCallback(c) |
@@ -150,45 +191,3 @@ func (c *Connection) handleTimeOut() { | @@ -150,45 +191,3 @@ func (c *Connection) handleTimeOut() { | ||
150 | func (c *Connection) Quitting() { | 191 | func (c *Connection) Quitting() { |
151 | c.Quit <- c | 192 | c.Quit <- c |
152 | } | 193 | } |
153 | - | ||
154 | -func (c *Connection) Start() { | ||
155 | - go c.write() | ||
156 | - go c.read() | ||
157 | - go c.listen() | ||
158 | - | ||
159 | - c.Status = 1 | ||
160 | - c.connectionCallback(c) | ||
161 | - c.handleTimeOut() | ||
162 | -} | ||
163 | - | ||
164 | -func (c *Connection) Stop() { | ||
165 | - logger.Debug("ID: %d close", c.Id) | ||
166 | - closed := atomic.LoadUint32(&c.Status) | ||
167 | - if closed == 0 { | ||
168 | - return | ||
169 | - } | ||
170 | - atomic.StoreUint32(&c.Status, 0) | ||
171 | - | ||
172 | - close(c.WBuffer) | ||
173 | - close(c.Quit) | ||
174 | - c.Conn.Close() | ||
175 | - c.closeCallback(c) | ||
176 | -} | ||
177 | - | ||
178 | -func (c *Connection) Send(errCode int32, cmd uint32, data []byte) error{ | ||
179 | - buf, err := c.Server.GetSplitter().Pack(cmd, data, errCode, 0) | ||
180 | - if err != nil { | ||
181 | - return err | ||
182 | - } | ||
183 | - | ||
184 | - sendTimeout := time.NewTimer(5 * time.Millisecond) | ||
185 | - defer sendTimeout.Stop() | ||
186 | - // 发送超时 | ||
187 | - select { | ||
188 | - case <-sendTimeout.C: | ||
189 | - return fmt.Errorf("send buff msg timeout") | ||
190 | - case c.WBuffer <- buf: | ||
191 | - return nil | ||
192 | - } | ||
193 | -} | ||
194 | - |
common/components/icompontents.go
@@ -54,6 +54,7 @@ type IServer interface { | @@ -54,6 +54,7 @@ type IServer interface { | ||
54 | 54 | ||
55 | GetSplitter() ISplitter | 55 | GetSplitter() ISplitter |
56 | GetIConnection(id int) IConnection | 56 | GetIConnection(id int) IConnection |
57 | + GetPlugin() IPlugin | ||
57 | 58 | ||
58 | SetConnectionCallback(ConnectionCallback) | 59 | SetConnectionCallback(ConnectionCallback) |
59 | SetMessageCallback(MessageCallback) | 60 | SetMessageCallback(MessageCallback) |
@@ -66,4 +67,11 @@ type IHttp interface { | @@ -66,4 +67,11 @@ type IHttp interface { | ||
66 | Start() error | 67 | Start() error |
67 | Stop() | 68 | Stop() |
68 | BindHandler(interface{}) | 69 | BindHandler(interface{}) |
70 | +} | ||
71 | + | ||
72 | +type ActionHandler func (conn IConnection, msg IMessage) (int32, interface{}) | ||
73 | +//用于热更逻辑的插件接口 | ||
74 | +type IPlugin interface { | ||
75 | + LoadPlugin() error | ||
76 | + GetAction(uint32) interface{} | ||
69 | } | 77 | } |
70 | \ No newline at end of file | 78 | \ No newline at end of file |
@@ -0,0 +1,62 @@ | @@ -0,0 +1,62 @@ | ||
1 | +package components | ||
2 | + | ||
3 | +import ( | ||
4 | + "plugin" | ||
5 | + "pro2d/pb" | ||
6 | + "pro2d/utils/logger" | ||
7 | + "sync" | ||
8 | +) | ||
9 | + | ||
10 | +type ActionMap sync.Map//map[pb.ProtoCode]ActionHandler | ||
11 | + | ||
12 | +type PluginOption func(*Plugin) | ||
13 | + | ||
14 | +type Plugin struct { | ||
15 | + pluginPath string | ||
16 | + | ||
17 | + Actions sync.Map | ||
18 | +} | ||
19 | + | ||
20 | +func NewPlugin(path string, options ...PluginOption) IPlugin{ | ||
21 | + p := &Plugin{ | ||
22 | + pluginPath: path, | ||
23 | + } | ||
24 | + for _, option := range options { | ||
25 | + option(p) | ||
26 | + } | ||
27 | + return p | ||
28 | +} | ||
29 | + | ||
30 | +func (p *Plugin) LoadPlugin() error { | ||
31 | + plu, err := plugin.Open(p.pluginPath) | ||
32 | + | ||
33 | + if err != nil { | ||
34 | + return err | ||
35 | + } | ||
36 | + logger.Debug("func LoadPlugin open success...") | ||
37 | + | ||
38 | + f, err := plu.Lookup("GetActionMap") | ||
39 | + if err != nil { | ||
40 | + return err | ||
41 | + } | ||
42 | + logger.Debug("func LoadPlugin Lookup success...") | ||
43 | + | ||
44 | + if x, ok := f.(func()map[interface{}]interface{}); ok { | ||
45 | + logger.Debug("func LoadPlugin GetActionMap success...") | ||
46 | + am := x() | ||
47 | + for k, v := range am { | ||
48 | + p.Actions.Delete(k) | ||
49 | + p.Actions.Store(k, v) | ||
50 | + } | ||
51 | + } | ||
52 | + | ||
53 | + return nil | ||
54 | +} | ||
55 | + | ||
56 | +func (p *Plugin) GetAction(cmd uint32) interface{} { | ||
57 | + f, ok := p.Actions.Load(pb.ProtoCode(cmd)) | ||
58 | + if !ok { | ||
59 | + return nil | ||
60 | + } | ||
61 | + return f | ||
62 | +} |
common/components/server.go
@@ -2,39 +2,74 @@ package components | @@ -2,39 +2,74 @@ package components | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | - "github.com/golang/protobuf/proto" | ||
6 | "net" | 5 | "net" |
7 | - "plugin" | ||
8 | - "pro2d/pb" | ||
9 | "pro2d/utils/logger" | 6 | "pro2d/utils/logger" |
10 | "sync" | 7 | "sync" |
11 | ) | 8 | ) |
12 | 9 | ||
13 | -type ActionHandler func (msg IMessage) (int32, proto.Message) | ||
14 | -var ActionMap map[pb.ProtoCode]ActionHandler | 10 | +type Option func(*Server) |
11 | + | ||
12 | +func WithPlugin(iPlugin IPlugin) Option { | ||
13 | + return func(server *Server) { | ||
14 | + server.plugins = iPlugin | ||
15 | + } | ||
16 | +} | ||
17 | + | ||
18 | +func WithSplitter(splitter ISplitter) Option { | ||
19 | + return func(server *Server) { | ||
20 | + server.splitter = splitter | ||
21 | + } | ||
22 | +} | ||
23 | + | ||
24 | +func WithConnCbk(cb ConnectionCallback) Option { | ||
25 | + return func(server *Server) { | ||
26 | + server.connectionCallback = cb | ||
27 | + } | ||
28 | +} | ||
29 | + | ||
30 | +func WithMsgCbk(cb MessageCallback) Option { | ||
31 | + return func(server *Server) { | ||
32 | + server.messageCallback = cb | ||
33 | + } | ||
34 | +} | ||
35 | + | ||
36 | +func WithCloseCbk(cb CloseCallback) Option { | ||
37 | + return func(server *Server) { | ||
38 | + server.closeCallback = cb | ||
39 | + } | ||
40 | +} | ||
41 | + | ||
42 | +func WithTimerCbk(cb TimerCallback) Option { | ||
43 | + return func(server *Server) { | ||
44 | + server.timerCallback = cb | ||
45 | + } | ||
46 | +} | ||
47 | + | ||
15 | 48 | ||
16 | type Server struct { | 49 | type Server struct { |
17 | - IServer | 50 | + PluginPath string |
51 | + plugins IPlugin | ||
52 | + splitter ISplitter | ||
53 | + actionHandlers sync.Map | ||
18 | 54 | ||
19 | connectionCallback ConnectionCallback | 55 | connectionCallback ConnectionCallback |
20 | messageCallback MessageCallback | 56 | messageCallback MessageCallback |
21 | closeCallback CloseCallback | 57 | closeCallback CloseCallback |
22 | timerCallback TimerCallback | 58 | timerCallback TimerCallback |
23 | 59 | ||
24 | - splitter ISplitter | ||
25 | - | ||
26 | port int | 60 | port int |
27 | - PluginPath string | ||
28 | Clients *sync.Map | 61 | Clients *sync.Map |
29 | } | 62 | } |
30 | 63 | ||
31 | -func NewServer(port int, pluginPath string, splitter ISplitter) *Server { | 64 | +func NewServer(port int, options ...Option) IServer { |
32 | s := &Server{ | 65 | s := &Server{ |
33 | - splitter: splitter, | ||
34 | port: port, | 66 | port: port, |
35 | - PluginPath: pluginPath, | ||
36 | Clients: new(sync.Map), | 67 | Clients: new(sync.Map), |
37 | } | 68 | } |
69 | + for _, option := range options { | ||
70 | + option(s) | ||
71 | + } | ||
72 | + | ||
38 | return s | 73 | return s |
39 | } | 74 | } |
40 | 75 | ||
@@ -50,6 +85,10 @@ func (s *Server) GetIConnection(id int) IConnection { | @@ -50,6 +85,10 @@ func (s *Server) GetIConnection(id int) IConnection { | ||
50 | return c.(IConnection) | 85 | return c.(IConnection) |
51 | } | 86 | } |
52 | 87 | ||
88 | +func (s *Server) GetPlugin() IPlugin { | ||
89 | + return s.plugins | ||
90 | +} | ||
91 | + | ||
53 | func (s *Server) SetConnectionCallback(cb ConnectionCallback) { | 92 | func (s *Server) SetConnectionCallback(cb ConnectionCallback) { |
54 | s.connectionCallback = cb | 93 | s.connectionCallback = cb |
55 | } | 94 | } |
@@ -82,23 +121,11 @@ func (s *Server) removeConnection(conn IConnection) { | @@ -82,23 +121,11 @@ func (s *Server) removeConnection(conn IConnection) { | ||
82 | s.Clients.Delete(conn.GetID()) | 121 | s.Clients.Delete(conn.GetID()) |
83 | } | 122 | } |
84 | 123 | ||
85 | -func (s *Server) LoadPlugin() { | ||
86 | - //重新加载 | ||
87 | - _, err:=plugin.Open(s.PluginPath) | ||
88 | - if err != nil { | ||
89 | - logger.Error("load plugin err: %v, %s", err, s.PluginPath) | ||
90 | - return | 124 | +func (s *Server) Start() error { |
125 | + if err := s.plugins.LoadPlugin(); err != nil { | ||
126 | + return err | ||
91 | } | 127 | } |
92 | - logger.Debug("load plugin success") | ||
93 | -} | ||
94 | 128 | ||
95 | - | ||
96 | -func (s *Server) Start() error { | ||
97 | - //初始化plugin | ||
98 | - //_, err = plugin.Open(conf.GlobalConf.GameConf.PluginPath) | ||
99 | - //if err != nil { | ||
100 | - // return err | ||
101 | - //} | ||
102 | port := fmt.Sprintf(":%d", s.port) | 129 | port := fmt.Sprintf(":%d", s.port) |
103 | l, err := net.Listen("tcp", port) | 130 | l, err := net.Listen("tcp", port) |
104 | if err != nil { | 131 | if err != nil { |
plugin/protocode.go deleted
@@ -1,17 +0,0 @@ | @@ -1,17 +0,0 @@ | ||
1 | -package plugin | ||
2 | - | ||
3 | -import ( | ||
4 | - "pro2d/common/components" | ||
5 | - "pro2d/pb" | ||
6 | - "pro2d/utils/logger" | ||
7 | -) | ||
8 | - | ||
9 | -func init() { | ||
10 | - logger.Debug("init protocode...") | ||
11 | - components.ActionMap = make(map[pb.ProtoCode]components.ActionHandler) | ||
12 | - | ||
13 | - components.ActionMap[pb.ProtoCode_HeartReq] = HeartRpc | ||
14 | - components.ActionMap[pb.ProtoCode_LoginReq] = LoginRpc | ||
15 | - components.ActionMap[pb.ProtoCode_CreateReq] = CreateRpc | ||
16 | - | ||
17 | -} |
tools/protostostruct.go
@@ -15,8 +15,8 @@ var ( | @@ -15,8 +15,8 @@ var ( | ||
15 | ProtoCodeLineReq = "\t%sReq = %d;\n" | 15 | ProtoCodeLineReq = "\t%sReq = %d;\n" |
16 | ProtoCodeLineRsp = "\t%sRsp = %d;\n" | 16 | ProtoCodeLineRsp = "\t%sRsp = %d;\n" |
17 | 17 | ||
18 | - GoProtoCodeStr = "package main\n\nimport (\n\t\"pro2d/pb\"\n\t\"pro2d/src/components/logger\"\n\t\"pro2d/src/components/net\"\n)\n\nfunc init() {\n\tlogger.Debug(\"init protocode...\")\n\tnet.ActionMap = make(map[pb.ProtoCode]net.ActionHandler)\n\n%s\n}\n" | ||
19 | - GoProtoCodeLine = "\tnet.ActionMap[pb.ProtoCode_%sReq] = %sRpc\n" | 18 | + GoProtoCodeStr = "package main\n\nimport (\n\t\"pro2d/pb\"\n\t\"pro2d/utils/logger\"\n)\n\nfunc GetActionMap() map[interface{}]interface{} {\n\tlogger.Debug(\"init protocode...\")\n\tam := make(map[interface{}]interface{})\n%s\n\treturn am\n}" |
19 | + GoProtoCodeLine = "\tam[pb.ProtoCode_%sReq] = %sRpc\n" | ||
20 | ) | 20 | ) |
21 | 21 | ||
22 | func ProtoToCode(readPath, filename string) (string, string) { | 22 | func ProtoToCode(readPath, filename string) (string, string) { |
@@ -106,7 +106,7 @@ func ReadProtos(readPath, OutPath string ) error { | @@ -106,7 +106,7 @@ func ReadProtos(readPath, OutPath string ) error { | ||
106 | return fmt.Errorf("WriteNewFile|Write is err:%v", err) | 106 | return fmt.Errorf("WriteNewFile|Write is err:%v", err) |
107 | } | 107 | } |
108 | 108 | ||
109 | - fw, err = os.OpenFile( OutPath+"src/plugin/protocode.go", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) | 109 | + fw, err = os.OpenFile( OutPath+"cmd/gameserver/plugin/protocode.go", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) |
110 | if err != nil { | 110 | if err != nil { |
111 | return fmt.Errorf("WriteNewFile|OpenFile is err:%v", err) | 111 | return fmt.Errorf("WriteNewFile|OpenFile is err:%v", err) |
112 | } | 112 | } |