diff --git a/_examples/test1_handler/profile/data_config/dropConfig.json b/_examples/profile_single/data_config/dropConfig.json similarity index 94% rename from _examples/test1_handler/profile/data_config/dropConfig.json rename to _examples/profile_single/data_config/dropConfig.json index a29e7f87..3e72bc9b 100644 --- a/_examples/test1_handler/profile/data_config/dropConfig.json +++ b/_examples/profile_single/data_config/dropConfig.json @@ -1,26 +1,26 @@ -[ - { - "dropId": 1001, - "itemType": 1, - "itemId": 2, - "num": 10, - "dropType": 2, - "dropValue": 10011 - }, - { - "dropId": 1002, - "itemType": 3, - "itemId": 10001, - "num": 1, - "dropType": 1, - "dropValue": 100 - }, - { - "dropId": 1002, - "itemType": 3, - "itemId": 10002, - "num": 1, - "dropType": 1, - "dropValue": 100 - } +[ + { + "dropId": 1001, + "itemType": 1, + "itemId": 2, + "num": 10, + "dropType": 2, + "dropValue": 10011 + }, + { + "dropId": 1002, + "itemType": 3, + "itemId": 10001, + "num": 1, + "dropType": 1, + "dropValue": 100 + }, + { + "dropId": 1002, + "itemType": 3, + "itemId": 10002, + "num": 1, + "dropType": 1, + "dropValue": 100 + } ] \ No newline at end of file diff --git a/_examples/test1_handler/profile/profile-local.json b/_examples/profile_single/profile-local.json similarity index 92% rename from _examples/test1_handler/profile/profile-local.json rename to _examples/profile_single/profile-local.json index 85008448..2e74f397 100644 --- a/_examples/test1_handler/profile/profile-local.json +++ b/_examples/profile_single/profile-local.json @@ -33,8 +33,8 @@ { "enable": true, "node_id": "web-1", - "address": ":10820", - "rpc_address": "127.0.0.1:20820", + "address": "127.0.0.1:10820", + "rpc_address": "127.0.0.1:30820", "__settings__": { "maintain_state": 2, "ref_logger": "game_log" diff --git a/_examples/test1_data_config/profile/common/logger.json b/_examples/profile_split/common/logger.json similarity index 95% rename from _examples/test1_data_config/profile/common/logger.json rename to _examples/profile_split/common/logger.json index a6550ca0..249d6a2c 100644 --- a/_examples/test1_data_config/profile/common/logger.json +++ b/_examples/profile_split/common/logger.json @@ -1,27 +1,27 @@ -{ - "logger": { - "game_log": { - "level": "debug", - "enable_write_file": false, - "enable_console": true, - "file_path": "logs/game.log", - "max_size": 128, - "max_age": 7, - "max_backups": 0, - "compress": false, - "time_format": "15:04:05.000", - "print_caller": true - }, - "test_handler": { - "level": "debug", - "enable_write_file": true, - "enable_console": false, - "file_path": "logs/test_handler.log", - "max_size": 128, - "max_age": 7, - "max_backups": 0, - "compress": false, - "time_format": "15:04:05.000" - } - } +{ + "logger": { + "game_log": { + "level": "debug", + "enable_write_file": false, + "enable_console": true, + "file_path": "logs/game.log", + "max_size": 128, + "max_age": 7, + "max_backups": 0, + "compress": false, + "time_format": "15:04:05.000", + "print_caller": true + }, + "test_handler": { + "level": "debug", + "enable_write_file": true, + "enable_console": false, + "file_path": "logs/test_handler.log", + "max_size": 128, + "max_age": 7, + "max_backups": 0, + "compress": false, + "time_format": "15:04:05.000" + } + } } \ No newline at end of file diff --git a/_examples/test1_data_config/profile/data_config/dropConfig.json b/_examples/profile_split/data_config/dropConfig.json similarity index 94% rename from _examples/test1_data_config/profile/data_config/dropConfig.json rename to _examples/profile_split/data_config/dropConfig.json index 1527236e..464e09b0 100644 --- a/_examples/test1_data_config/profile/data_config/dropConfig.json +++ b/_examples/profile_split/data_config/dropConfig.json @@ -1,27 +1,27 @@ -[ - { - "dropId": 1011, - "itemType": 1, - "itemId": 2, - "num": 10, - "dropType": 2, - "dropValue": 2, - "desc": "desc test1" - }, - { - "dropId": 1002, - "itemType": 3, - "itemId": 10001, - "num": 1, - "dropType": 1, - "dropValue": 10 - }, - { - "dropId": 1002, - "itemType": 3, - "itemId": 10002, - "num": 1, - "dropType": 1, - "dropValue": 100 - } +[ + { + "dropId": 1011, + "itemType": 1, + "itemId": 2, + "num": 10, + "dropType": 2, + "dropValue": 2, + "desc": "desc test1" + }, + { + "dropId": 1002, + "itemType": 3, + "itemId": 10001, + "num": 1, + "dropType": 1, + "dropValue": 10 + }, + { + "dropId": 1002, + "itemType": 3, + "itemId": 10002, + "num": 1, + "dropType": 1, + "dropValue": 100 + } ] \ No newline at end of file diff --git a/_examples/test1_data_config/profile/data_config/dropOneConfig.json b/_examples/profile_split/data_config/dropOneConfig.json similarity index 94% rename from _examples/test1_data_config/profile/data_config/dropOneConfig.json rename to _examples/profile_split/data_config/dropOneConfig.json index 3ee13433..ce9df2ad 100644 --- a/_examples/test1_data_config/profile/data_config/dropOneConfig.json +++ b/_examples/profile_split/data_config/dropOneConfig.json @@ -1,9 +1,9 @@ -{ - "dropId": 9011, - "itemType": 91, - "itemId": 93, - "num": 90, - "dropType": 92, - "dropValue": 9, - "desc": "desc1111222" +{ + "dropId": 9011, + "itemType": 91, + "itemId": 93, + "num": 90, + "dropType": 92, + "dropValue": 9, + "desc": "desc1111222" } \ No newline at end of file diff --git a/_examples/test1_data_config/profile/profile-local-cluster.json b/_examples/profile_split/profile-local-cluster.json similarity index 95% rename from _examples/test1_data_config/profile/profile-local-cluster.json rename to _examples/profile_split/profile-local-cluster.json index 629a1566..4f96f8ba 100644 --- a/_examples/test1_data_config/profile/profile-local-cluster.json +++ b/_examples/profile_split/profile-local-cluster.json @@ -1,36 +1,36 @@ -{ - "cluster": { - "mode": "nodes", - "nodes": { - "web": [ - { - "enable": true, - "node_id": "web-1", - "address": ":10820", - "rpc_address": "127.0.0.1:20820", - "__settings__": { - "maintain_state": 2, - "@ref_logger": "game_log" - } - } - ], - "game": [ - { - "enable": true, - "node_id": "game-1", - "address": ":10860", - "rpc_address": "127.0.0.1:20860", - "__settings__": { - "maintain_state": 2, - "dbs": [ - "x_game-1" - ], - "ref_logger": "game_log" - } - } - ] - }, - "etcd": { - } - } +{ + "cluster": { + "mode": "nodes", + "nodes": { + "web": [ + { + "enable": true, + "node_id": "web-1", + "address": ":10820", + "rpc_address": "127.0.0.1:20820", + "__settings__": { + "maintain_state": 2, + "@ref_logger": "game_log" + } + } + ], + "game": [ + { + "enable": true, + "node_id": "game-1", + "address": ":10860", + "rpc_address": "127.0.0.1:20860", + "__settings__": { + "maintain_state": 2, + "dbs": [ + "x_game-1" + ], + "ref_logger": "game_log" + } + } + ] + }, + "etcd": { + } + } } \ No newline at end of file diff --git a/_examples/test1_data_config/profile/profile-local-data-config.json b/_examples/profile_split/profile-local-data-config.json similarity index 94% rename from _examples/test1_data_config/profile/profile-local-data-config.json rename to _examples/profile_split/profile-local-data-config.json index 6abefdc0..6e1540c1 100644 --- a/_examples/test1_data_config/profile/profile-local-data-config.json +++ b/_examples/profile_split/profile-local-data-config.json @@ -1,14 +1,14 @@ -{ - "data_config": { - "parser": "json", - "data_source": "file", - "file": { - "file_path": "data_config/", - "ext_name": ".json", - "reload_time": 3000 - }, - "redis": { - "redis_key": "config:server:xgame" - } - } +{ + "data_config": { + "parser": "json", + "data_source": "file", + "file": { + "file_path": "data_config/", + "ext_name": ".json", + "reload_time": 3000 + }, + "redis": { + "redis_key": "config:server:xgame" + } + } } \ No newline at end of file diff --git a/_examples/test1_data_config/profile/profile-local.json b/_examples/profile_split/profile-local.json similarity index 95% rename from _examples/test1_data_config/profile/profile-local.json rename to _examples/profile_split/profile-local.json index 13f47025..e8a911a2 100644 --- a/_examples/test1_data_config/profile/profile-local.json +++ b/_examples/profile_split/profile-local.json @@ -1,34 +1,34 @@ -{ - "debug": true, - "include": [ - "common/logger.json", - "profile-local-cluster.json", - "profile-local-data-config.json" - ], - "db": [ - { - "enable": true, - "group_id": "center_db", - "id": "center_db", - "db_name": "dev_xgame_center", - "host": "192.168.1.20", - "user_name": "gameserver", - "password": "password", - "max_idle_connect": 4, - "max_open_connect": 8, - "log_mode": true - }, - { - "enable": true, - "group_id": "game_db", - "id": "game_db_1", - "db_name": "game_db_1", - "host": "192.168.1.20", - "user_name": "gameserver", - "password": "password", - "max_idle_connect": 4, - "max_open_connect": 8, - "log_mode": true - } - ] +{ + "debug": true, + "include": [ + "common/logger.json", + "profile-local-cluster.json", + "profile-local-data-config.json" + ], + "db": [ + { + "enable": true, + "group_id": "center_db", + "id": "center_db", + "db_name": "dev_xgame_center", + "host": "192.168.1.20", + "user_name": "gameserver", + "password": "password", + "max_idle_connect": 4, + "max_open_connect": 8, + "log_mode": true + }, + { + "enable": true, + "group_id": "game_db", + "id": "game_db_1", + "db_name": "game_db_1", + "host": "192.168.1.20", + "user_name": "gameserver", + "password": "password", + "max_idle_connect": 4, + "max_open_connect": 8, + "log_mode": true + } + ] } \ No newline at end of file diff --git a/_examples/test1_data_config/main.go b/_examples/test1_data_config/main.go index 2383b9aa..18c39b24 100644 --- a/_examples/test1_data_config/main.go +++ b/_examples/test1_data_config/main.go @@ -13,7 +13,7 @@ func main() { } func app() { - testApp := cherry.NewDefaultApp() + testApp := cherry.NewApp("../profile_split/", "local", "game-1") defer testApp.OnShutdown() diff --git a/_examples/test1_handler/main.go b/_examples/test1_handler/main.go index 422b7c2d..55fcefa0 100644 --- a/_examples/test1_handler/main.go +++ b/_examples/test1_handler/main.go @@ -18,7 +18,7 @@ func main() { } func app() { - testApp := cherry.NewDefaultApp() + testApp := cherry.NewApp("../profile_single/", "local", "game-1") defer testApp.OnShutdown( func() { diff --git a/_examples/test_gin/main.go b/_examples/test_gin/main.go index b7a232c4..364fb404 100644 --- a/_examples/test_gin/main.go +++ b/_examples/test_gin/main.go @@ -6,7 +6,7 @@ import ( ) func main() { - testApp := cherry.NewDefaultApp() + testApp := cherry.NewApp("../profile_single/", "local", "web-1") defer testApp.OnShutdown() httpServer := cherryGin.NewHttp("http_server_1", testApp.ThisNode().Address()) diff --git a/_examples/test_gin/profile/profile-local.json b/_examples/test_gin/profile/profile-local.json deleted file mode 100644 index d001a7b4..00000000 --- a/_examples/test_gin/profile/profile-local.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "debug": true, - "logger": { - "game_log": { - "level": "debug", - "enable_write_file": false, - "file_path": "logs/game.log", - "max_size": 100, - "max_age": 7, - "max_backups": 0, - "compress": false, - "time_format": "15:04:05.000" - }, - "game_1_log": { - "level": "debug", - "enable_write_file": false, - "file_path": "logs/game.log", - "max_size": 100, - "max_age": 7, - "max_backups": 0, - "compress": false, - "time_format": "15:04:05.000" - } - }, - "cluster": { - "mode": "nodes", - "nodes": { - "web": [ - { - "enable": true, - "node_id": "web-1", - "address": ":10820", - "rpc_address": ":20820", - "__settings__": { - "maintain_state": 2, - "ref_logger": "game_log" - } - } - ], - "game": [ - { - "enable": true, - "node_id": "game-1", - "address": "127.0.0.1:10860", - "rpc_address": ":20860", - "__settings__": { - "maintain_state": 2, - "dbs": [ - "x_game-1" - ], - "ref_logger": "game_log" - } - } - ] - }, - "etcd": { - } - }, - "data_config": { - "data_source": "file", - "file": { - "file_path": "/data_config", - "reload_flush_time": 3000 - }, - "redis": { - "redis_key": "config:server:xgame" - } - }, - "db_queue": { - "db_pool_size": "4", - "table_submit_frequency": "1000", - "table_submit_num": "200", - "shutdown_table_submit_frequency": "1000", - "shutdown_table_submit_num": "200" - }, - "db": [ - { - "enable": true, - "group_id": "center_db", - "id": "center_db", - "db_name": "dev_xgame_center", - "host": "192.168.1.20", - "user_name": "gameserver", - "password": "password", - "max_idle_connect": 4, - "max_open_connect": 8, - "log_mode": true - }, - { - "enable": true, - "group_id": "game_db", - "id": "game_db_1", - "db_name": "game_db_1", - "host": "192.168.1.20", - "user_name": "gameserver", - "password": "password", - "max_idle_connect": 4, - "max_open_connect": 8, - "log_mode": true - } - ] -} \ No newline at end of file diff --git a/_examples/test_logger/profile/profile-local.json b/_examples/test_logger/profile/profile-local.json deleted file mode 100644 index 96ee0bf7..00000000 --- a/_examples/test_logger/profile/profile-local.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "debug": true, - "logger": { - "game_log": { - "level": "debug", - "enable_write_file": false, - "file_path": "logs/game.log", - "max_size": 128, - "max_age": 7, - "max_backups": 0, - "compress": false, - "time_format": "15:04:05.000", - "print_caller": true - }, - "test_handler": { - "is_write_file": true, - "file_path": "logs/test_handler.log", - "level": "debug", - "max_size": 128, - "max_age": 7, - "max_backups": 0, - "compress": false, - "time_format": "15:04:05.000" - } - }, - "cluster": { - "mode": "nodes", - "nodes": { - "web": [ - { - "enable": true, - "node_id": "web-1", - "address": ":10820", - "rpc_address": "127.0.0.1:20820", - "__settings__": { - "maintain_state": 2, - "ref_logger": "game_log" - } - } - ], - "game": [ - { - "enable": true, - "node_id": "game-1", - "address": ":10860", - "rpc_address": "127.0.0.1:20860", - "__settings__": { - "maintain_state": 2, - "dbs": [ - "x_game-1" - ], - "ref_logger": "game_log" - } - } - ] - }, - "etcd": { - } - }, - "data_config": { - "parser": "json", - "data_source": "file", - "file": { - "file_path": "data_config/", - "ext_name": ".json", - "reload_time": 3000 - }, - "redis": { - "redis_key": "config:server:xgame" - } - }, - "db_queue": { - "db_pool_size": "4", - "table_submit_frequency": "1000", - "table_submit_num": "200", - "shutdown_table_submit_frequency": "1000", - "shutdown_table_submit_num": "200" - }, - "db": [ - { - "enable": true, - "group_id": "center_db", - "id": "center_db", - "db_name": "dev_xgame_center", - "host": "192.168.1.20", - "user_name": "gameserver", - "password": "password", - "max_idle_connect": 4, - "max_open_connect": 8, - "log_mode": true - }, - { - "enable": true, - "group_id": "game_db", - "id": "game_db_1", - "db_name": "game_db_1", - "host": "192.168.1.20", - "user_name": "gameserver", - "password": "password", - "max_idle_connect": 4, - "max_open_connect": 8, - "log_mode": true - } - ] -} \ No newline at end of file diff --git a/cherry.go b/cherry.go index 83d812ed..e1717941 100644 --- a/cherry.go +++ b/cherry.go @@ -27,10 +27,6 @@ func NewDefaultApp() *Application { return NewApp(configPath, profile, nodeId) } -func NewNodeApp(profileName, nodeId string) *Application { - return NewApp("./profile", profileName, nodeId) -} - // NewApp create new application instance func NewApp(profilePath, profileName, nodeId string) *Application { config, err := cherryProfile.Init(profilePath, profileName) diff --git a/facade/session.go b/facade/session.go index 6011159c..b20e2cb9 100644 --- a/facade/session.go +++ b/facade/session.go @@ -9,10 +9,10 @@ type ( // INetwork 网络处理接口 INetwork interface { - SendRaw(bytes []byte) error Push(route string, v interface{}) error // 推送消息对客户端 Response(mid uint64, v interface{}) error // 回复消息到客户端 - Kick(reason string) // 踢下线 + Kick(reason string) error // 踢下线 + SendRaw(bytes []byte) error // write raw data to client RPC(route string, v interface{}) error // 调用rpc Close() // 关闭接口 RemoteAddr() net.Addr // 连接者的地址信息 diff --git a/go.mod b/go.mod index dff52e9f..2515cd2a 100644 --- a/go.mod +++ b/go.mod @@ -16,5 +16,4 @@ require ( gopkg.in/natefinch/lumberjack.v2 v2.0.0 gorm.io/driver/mysql v1.0.2 gorm.io/gorm v1.20.5 - ) diff --git a/go.sum b/go.sum index 307ed58e..ee644d4c 100644 --- a/go.sum +++ b/go.sum @@ -80,13 +80,19 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= diff --git a/net/agent/agent.go b/net/agent/agent.go index 7014a627..b5a041aa 100644 --- a/net/agent/agent.go +++ b/net/agent/agent.go @@ -9,14 +9,13 @@ import ( "github.com/cherry-game/cherry/net/packet" "github.com/cherry-game/cherry/net/session" "github.com/cherry-game/cherry/profile" - "log" "net" "sync/atomic" "time" ) const ( - agentWriteBacklog = 128 + agentWriteBacklog = 64 ) const ( @@ -150,14 +149,26 @@ func (a *Agent) RPC(route string, v interface{}) error { return nil } -// ResponseMid, implementation for session.NetworkEntity interface +// Response, implementation for session.NetworkEntity interface // Response message to session func (a *Agent) Response(mid uint64, v interface{}) error { return a.Send(cherryMessage.TypeResponse, "", mid, v) } -func (a *Agent) Kick(reason string) { - //TODO ... +// Kick +func (a *Agent) Kick(reason string) error { + pkg, err := a.PacketEncoder.Encode(cherryPacket.Kick, nil) + if err != nil { + return err + } + + _, err = a.Conn.Write(pkg) + if err != nil { + cherryLogger.Warn(err) + } + + cherryLogger.Debugf("kick session[%s] reason[%s]", a.Session, reason) + return nil } // Close closes the Agent, clean inner state and close low-level connection. @@ -184,7 +195,7 @@ func (a *Agent) Close() { } if err := a.Conn.Close(); err != nil { - cherryLogger.Errorf("session close error. session:%s, error:%v", a.Session, err) + cherryLogger.Errorf("session close error. session[%s], error:%v", a.Session, err) } } @@ -229,14 +240,13 @@ func (a *Agent) read() { for { msg, err := a.Conn.GetNextMessage() if err != nil { - cherryLogger.Debugf("session will be closed immediately. %s", err.Error()) + cherryLogger.Debugf("session[%s] will be closed immediately. %s", a.Session, err.Error()) return } packets, err := a.PacketDecoder.Decode(msg) if err != nil { - cherryLogger.Warnf("packet decoder error. error = %s", err) - cherryLogger.Debugf("msg= %s", msg) + cherryLogger.Warnf("packet decoder error. %s, msg[%s]", err, msg) continue } @@ -259,12 +269,6 @@ func (a *Agent) write() { for { select { - case <-ticker.C: - // 超过2倍心跳时间,还没有发消息到服务器,则断开 - deadline := time.Now().Add(-2 * a.Heartbeat).Unix() - if a.lastAt < deadline { - return - } case bytes := <-a.chWrite: // close Agent while low-level conn broken _, err := a.Conn.Write(bytes) @@ -272,11 +276,17 @@ func (a *Agent) write() { cherryLogger.Error(err) return } - + case <-ticker.C: + // double timeout + deadline := time.Now().Add(-2 * a.Heartbeat).Unix() + if a.lastAt < deadline { + cherryLogger.Debugf("connect heartbeat timeout. session[%s]", a.Session) + return + } case data := <-a.chSend: payload, err := a.Serializer.Marshal(data.payload) if err != nil { - cherryLogger.Debugf("message serializer error. %s", data.String()) + cherryLogger.Debugf("message serializer error. session[%s], data[%s]", a.Session, data.String()) return } @@ -298,7 +308,7 @@ func (a *Agent) write() { // encode packet p, err := a.PacketEncoder.Encode(cherryPacket.Data, em) if err != nil { - log.Println(err) + cherryLogger.Warn(err) break } a.chWrite <- p diff --git a/net/connector/component.go b/net/connector/component.go index 19ddbe98..91cf5792 100644 --- a/net/connector/component.go +++ b/net/connector/component.go @@ -24,17 +24,17 @@ type ( sessionComponent *cherrySession.SessionComponent handlerComponent *cherryHandler.Component connector facade.IConnector - packetHandles map[byte]cherryAgent.PacketListener + packetHandles map[cherryPacket.Type]cherryAgent.PacketListener } ) var ( - defaultHeartbeat = 15 * time.Second + DefaultHeartbeat = 30 * time.Second ) func NewTCPComponent(address string) *Component { opt := cherryAgent.Options{ - Heartbeat: defaultHeartbeat, + Heartbeat: DefaultHeartbeat, DataCompression: false, PacketDecoder: cherryPacket.NewPomeloDecoder(), PacketEncoder: cherryPacket.NewPomeloEncoder(), @@ -51,7 +51,7 @@ func NewTCPComponent(address string) *Component { func NewWSComponent(address string) *Component { opt := cherryAgent.Options{ - Heartbeat: defaultHeartbeat, + Heartbeat: DefaultHeartbeat, DataCompression: false, PacketDecoder: cherryPacket.NewPomeloDecoder(), PacketEncoder: cherryPacket.NewPomeloEncoder(), @@ -71,7 +71,7 @@ func NewConnectorWithOpt(opts cherryAgent.Options, connector facade.IConnector) Options: opts, connector: connector, ConnectStat: &ConnectStat{}, - packetHandles: make(map[byte]cherryAgent.PacketListener), + packetHandles: make(map[cherryPacket.Type]cherryAgent.PacketListener), } } @@ -100,7 +100,7 @@ func (p *Component) OnAfterInit() { p.OnCreateSession(func(s *cherrySession.Session) (next bool, err error) { // increase connect stat p.ConnectStat.IncreaseConn() - cherryLogger.Debugf("after create. session:%s", s) + cherryLogger.Debugf("session[%s] on create.", s) return true, nil }) @@ -115,7 +115,7 @@ func (p *Component) OnAfterInit() { p.PacketListener = func(agent *cherryAgent.Agent, packet *cherryPacket.Packet) { fn, found := p.packetHandles[packet.Type] if found == false { - cherryLogger.Errorf("packet type not found. session = %s, packet = %s", + cherryLogger.Errorf("session[%s], packet[%s] type not found.", agent.Session, packet, ) @@ -164,7 +164,7 @@ func (p *Component) OnCloseSession(listener ...cherryAgent.SessionListener) { p.OnCloseListener = append(p.OnCloseListener, listener...) } -func (p *Component) SetPacketHandle(typ byte, listener cherryAgent.PacketListener) { +func (p *Component) SetPacketHandle(typ cherryPacket.Type, listener cherryAgent.PacketListener) { p.packetHandles[typ] = listener } @@ -191,13 +191,13 @@ func (p *Component) handshake(agent *cherryAgent.Agent, _ *cherryPacket.Packet) cherryLogger.Error(err) } - cherryLogger.Debugf("sid = %d, request handshake", agent.Session.SID()) + cherryLogger.Debugf("session[%s] request handshake", agent.Session) } func (p *Component) handshakeACK(agent *cherryAgent.Agent, _ *cherryPacket.Packet) { agent.SetStatus(cherryAgent.Working) - cherryLogger.Debugf("sid = %d, request handshakeACK", agent.Session.SID()) + cherryLogger.Debugf("session[%s] request handshakeACK", agent.Session) } func (p *Component) heartbeat(agent *cherryAgent.Agent, _ *cherryPacket.Packet) { @@ -211,13 +211,13 @@ func (p *Component) heartbeat(agent *cherryAgent.Agent, _ *cherryPacket.Packet) if err != nil { cherryLogger.Error(err) } - cherryLogger.Debugf("sid = %d, request heartbeat", agent.Session.SID()) + cherryLogger.Debugf("session[%s],, request heartbeat", agent.Session) } func (p *Component) handData(agent *cherryAgent.Agent, pkg *cherryPacket.Packet) { if agent.Status() != cherryAgent.Working { - cherryLogger.Warnf("status is not working. session=[%s]", agent.Session) + cherryLogger.Warnf("status is not working. session[%s]", agent.Session) return } @@ -229,7 +229,7 @@ func (p *Component) handData(agent *cherryAgent.Agent, route, err := cherryRoute.Decode(msg.Route) if err != nil { - cherryLogger.Errorf("route decode error. session = [%s] message = [%s]", agent.Session, msg) + cherryLogger.Errorf("route decode error. session[%s] message[%s]", agent.Session, msg) return } diff --git a/net/connector/ws_connector.go b/net/connector/ws_connector.go index af9a01c5..7fcbb2bb 100644 --- a/net/connector/ws_connector.go +++ b/net/connector/ws_connector.go @@ -137,11 +137,13 @@ func (c *wsConn) GetNextMessage() (b []byte, err error) { if err != nil { return nil, err } + if len(msgBytes) < cherryPacket.HeadLength { return nil, cherryError.PacketInvalidHeader } header := msgBytes[:cherryPacket.HeadLength] + msgSize, _, err := cherryPacket.ParseHeader(header) if err != nil { return nil, err @@ -149,11 +151,10 @@ func (c *wsConn) GetNextMessage() (b []byte, err error) { dataLen := len(msgBytes[cherryPacket.HeadLength:]) - if dataLen < msgSize { - return nil, cherryError.PacketMsgSmallerThanExpected - } else if dataLen > msgSize { + if dataLen < msgSize || dataLen > msgSize { return nil, cherryError.PacketMsgSmallerThanExpected } + return msgBytes, err } diff --git a/net/handler/component.go b/net/handler/component.go index 73da0c70..525d6fdf 100644 --- a/net/handler/component.go +++ b/net/handler/component.go @@ -1,6 +1,7 @@ package cherryHandler import ( + "fmt" "github.com/cherry-game/cherry/const" "github.com/cherry-game/cherry/extend/reflect" facade "github.com/cherry-game/cherry/facade" @@ -34,6 +35,10 @@ type ( FilterFn func(msg *UnhandledMessage) bool ) +func (u *UnhandledMessage) String() string { + return fmt.Sprintf("session[%s], route[%s], msg[%s] ", u.Session, u.Route, u.Msg) +} + func NewComponent() *Component { return &Component{ handlers: make(map[string]facade.IHandler), @@ -133,7 +138,7 @@ func (h *Component) DoHandle(msg *UnhandledMessage) { func (h *Component) doForward(msg *UnhandledMessage) { // TODO 通过rpc 转发到远程节点 // rpc client invoke - cherryLogger.Debugf("forward message = %s", msg) + cherryLogger.Debugf("forward message. %s", msg) } func (h *Component) GetHandler(route *cherryRoute.Route) facade.IHandler { diff --git a/net/packet/constant.go b/net/packet/constant.go index c545b18c..41fd2891 100644 --- a/net/packet/constant.go +++ b/net/packet/constant.go @@ -1,23 +1,42 @@ package cherryPacket +type Type byte + +var types = map[Type]string{ + None: "None", + Handshake: "Handshake", + HandshakeAck: "HandshakeAck", + Heartbeat: "Heartbeat", + Data: "Data", + Kick: "Kick", +} + +func (t *Type) String() string { + return types[*t] +} + +func invalidType(t Type) bool { + return t < Handshake || t > Kick +} + const ( // None - None = 0x00 + None Type = 0x00 // Handshake represents a handshake: request(client) <====> handshake response(server) - Handshake = 0x01 + Handshake Type = 0x01 // HandshakeAck represents a handshake ack from client to server - HandshakeAck = 0x02 + HandshakeAck Type = 0x02 // Heartbeat represents a heartbeat - Heartbeat = 0x03 + Heartbeat Type = 0x03 // Settings represents a common data packet - Data = 0x04 + Data Type = 0x04 // Kick represents a kick off packet - Kick = 0x05 // disconnect message from server + Kick Type = 0x05 // disconnect message from server ) var HeadLength = 4 // 4 bytes diff --git a/net/packet/packet.go b/net/packet/packet.go index 33ec2aa6..0c1d6d4d 100644 --- a/net/packet/packet.go +++ b/net/packet/packet.go @@ -13,37 +13,37 @@ type ( // Encoder Encoder interface { - Encode(typ byte, buf []byte) ([]byte, error) + Encode(typ Type, buf []byte) ([]byte, error) } ) // Packet 网络消息包结构 type Packet struct { - Type byte // 包类型 + Type Type // 包类型 Length int // 包长度 Data []byte // 数据内容 message } // String represents the Packet's in text mode. func (p *Packet) String() string { - return fmt.Sprintf("Packet Type: %d, Length: %d, Data: %s", p.Type, p.Length, string(p.Data)) + return fmt.Sprintf("packet type: %s, length: %d, data: %s", p.Type.String(), p.Length, string(p.Data)) } // ParseHeader parses a packet header and returns its dataLen and packetType or an error -func ParseHeader(header []byte) (int, byte, error) { +func ParseHeader(header []byte) (int, Type, error) { if len(header) != HeadLength { - return 0, 0x00, cherryError.PacketInvalidHeader + return 0, None, cherryError.PacketInvalidHeader } typ := header[0] - if typ < Handshake || typ > Kick { + if invalidType(Type(typ)) { return 0, None, cherryError.PacketWrongType } size := BytesToInt(header[1:]) if size > MaxPacketSize { - return 0, 0x00, cherryError.PacketSizeExceed + return 0, None, cherryError.PacketSizeExceed } - return size, typ, nil + return size, Type(typ), nil } diff --git a/net/packet/pomelo_decoder.go b/net/packet/pomelo_decoder.go index 99315392..443cb371 100644 --- a/net/packet/pomelo_decoder.go +++ b/net/packet/pomelo_decoder.go @@ -53,12 +53,12 @@ func (p *PomeloDecoder) Decode(data []byte) ([]*Packet, error) { return packets, nil } -func (p *PomeloDecoder) forward(buf *bytes.Buffer) (int, byte, error) { +func (p *PomeloDecoder) forward(buf *bytes.Buffer) (int, Type, error) { header := buf.Next(HeadLength) typ := header[0] - if typ < Handshake || typ > Kick { - return 0, 0x00, cherryError.PacketSizeExceed + if invalidType(Type(typ)) { + return 0, None, cherryError.PacketSizeExceed } // get 2,3,4 byte @@ -66,10 +66,10 @@ func (p *PomeloDecoder) forward(buf *bytes.Buffer) (int, byte, error) { // packet length limitation if size > MaxPacketSize { - return 0, 0x00, cherryError.PacketSizeExceed + return 0, None, cherryError.PacketSizeExceed } - return size, typ, nil + return size, Type(typ), nil } // Decode packet data length byte to int(Big end) diff --git a/net/packet/pomelo_encoder.go b/net/packet/pomelo_encoder.go index 9b7c63f5..2074f597 100644 --- a/net/packet/pomelo_encoder.go +++ b/net/packet/pomelo_encoder.go @@ -15,7 +15,7 @@ func NewPomeloEncoder() *PomeloEncoder { // --|----------------|-- // --------|------------------------|-------- // 1 byte packet type, 3 bytes packet data length(big end), and data segment -func (p *PomeloEncoder) Encode(typ byte, data []byte) ([]byte, error) { +func (p *PomeloEncoder) Encode(typ Type, data []byte) ([]byte, error) { if typ < Handshake || typ > Kick { return nil, cherryError.PacketWrongType } @@ -33,7 +33,7 @@ func (p *PomeloEncoder) Encode(typ byte, data []byte) ([]byte, error) { buf := make([]byte, pkg.Length+HeadLength) //第一个字节存放消息类型 - buf[0] = pkg.Type + buf[0] = byte(pkg.Type) //2~4 字节 存放消息长度 copy(buf[1:HeadLength], IntToBytes(pkg.Length)) diff --git a/net/session/session.go b/net/session/session.go index 0c580793..bf03663e 100644 --- a/net/session/session.go +++ b/net/session/session.go @@ -86,12 +86,22 @@ func (s *Session) Push(route string, v interface{}) error { return s.entity.Push(route, v) } -// ResponseMID responses message to client, mid is +// Response responses message to client, mid is // request message ID -func (s *Session) ResponseMID(mid uint64, v interface{}) error { +func (s *Session) Response(mid uint64, v interface{}) error { return s.entity.Response(mid, v) } +func (s *Session) Kick(reason string) error { + err := s.entity.Kick(reason) + if err != nil { + return err + } + + s.Closed() + return nil +} + func (s *Session) Closed() { s.entity.Close() }