Compare commits

...

197 Commits

Author SHA1 Message Date
azw
7eb242f5b8 1 2023-06-09 06:57:46 +00:00
azw
571a29eebb 1 2023-06-05 09:50:17 +00:00
azw
70e076631c 1 2023-06-05 09:41:56 +00:00
azw
39b01b2794 1 2023-06-05 09:40:34 +00:00
azw
36f7099354 1 2023-06-05 09:36:21 +00:00
azw
90d4fbac8c 1 2023-04-27 09:16:09 +00:00
azw
6889784621 优化内存泄露问题 2023-04-27 08:59:26 +00:00
azw
10db780deb 1 2023-04-27 06:41:08 +00:00
azw
52e3f33006 1 2023-04-27 06:20:38 +00:00
azw
7b8cd6c11b 1 2023-04-27 06:15:34 +00:00
azw
2b975c2cfb 1 2023-04-27 03:53:13 +00:00
azw
4f4c124f44 1 2023-04-27 03:47:34 +00:00
azw
3641e6f4c6 1 2023-04-26 08:15:22 +00:00
azw
ccacf371bf 1 2023-04-26 07:56:25 +00:00
azw
9fb8c7c51a 1 2023-04-26 06:58:30 +00:00
azw
a4e1fbd27e 1 2023-04-25 08:54:58 +00:00
azw
6b36492bb1 1 2023-04-25 08:19:40 +00:00
azw
9f7276a776 1 2023-04-25 07:00:25 +00:00
azw
86a709acbf 1 2023-04-25 06:26:22 +00:00
azw
d7ea1075ab 1 2023-04-25 06:06:51 +00:00
azw
adfa92a169 1 2023-04-25 05:59:41 +00:00
azw
7e1cfb2e10 1 2023-04-25 04:14:38 +00:00
azw
a986ff484d 1 2023-04-25 03:50:08 +00:00
azw
ce2679496a 1 2023-04-25 03:47:00 +00:00
azw
3a81c9ed37 1 2023-04-25 03:39:24 +00:00
azw
499114b744 1 2023-04-25 03:31:56 +00:00
azw
5da25c735d 1 2023-04-25 03:20:09 +00:00
azw
acc4ae8a67 1 2023-04-25 02:53:44 +00:00
azw
8fb293e9e4 1 2023-04-25 02:28:15 +00:00
azw
15f49da6c1 1 2023-04-24 11:46:34 +00:00
azw
809297d9a6 1 2023-04-24 11:42:36 +00:00
azw
0ec8f9133b 1 2023-04-24 11:30:57 +00:00
azw
415f509878 1 2023-04-24 11:26:39 +00:00
azw
1e87e6ddf2 1 2023-04-24 11:24:59 +00:00
azw
8049cd7da8 1 2023-04-24 11:21:59 +00:00
azw
c73efe1f71 1 2023-04-24 11:20:26 +00:00
azw
8ef28cf556 1 2023-04-24 11:18:04 +00:00
azw
5587c3c85c 1 2023-04-24 11:12:32 +00:00
azw
a490983b75 1 2023-04-24 11:02:28 +00:00
azw
b24c4c73e7 1 2023-04-24 10:59:58 +00:00
azw
2a4941c0b1 1 2023-04-24 09:47:53 +00:00
azw
09aad454d6 1 2023-04-24 08:31:16 +00:00
azw
9c0e8beab0 1 2023-04-24 08:24:22 +00:00
azw
aacd2fdc5f 1 2023-04-24 08:20:28 +00:00
azw
60800e90b7 1 2023-04-24 08:18:49 +00:00
azw
74f415b707 1 2023-04-24 08:16:39 +00:00
azw
10f58e24ca 1 2023-04-24 07:59:49 +00:00
azw
afe06bb99c 1 2023-04-24 07:40:28 +00:00
azw
d1143afd28 1 2023-04-24 07:35:53 +00:00
azw
bc48f98858 1 2023-04-24 07:34:13 +00:00
azw
f03826a582 1 2023-04-24 07:32:47 +00:00
aozhiwei
b957ba9682 1 2023-04-24 15:27:51 +08:00
aozhiwei
0ed4c1f3e2 1 2023-04-24 15:27:41 +08:00
azw
eecf02b2a4 1 2023-04-24 07:23:58 +00:00
azw
00f7a3663b 1 2023-04-24 07:21:39 +00:00
aozhiwei
a480c642bf 1 2023-04-24 14:35:37 +08:00
aozhiwei
b038b27c40 1 2023-04-24 14:30:45 +08:00
azw
62b4b5829b 1 2023-04-24 06:13:24 +00:00
aozhiwei
7ef9a15cc4 1 2023-04-24 13:34:30 +08:00
aozhiwei
caaf17bf26 1 2023-04-24 13:26:05 +08:00
aozhiwei
b9f09fd360 1 2023-04-24 13:22:53 +08:00
aozhiwei
55268bb0fd 1 2023-04-24 13:20:23 +08:00
aozhiwei
80cd4c08fb 1 2023-04-24 13:10:29 +08:00
aozhiwei
6ac513f73a 1 2023-04-24 12:05:02 +08:00
aozhiwei
b424a98f9c 1 2023-04-24 12:03:30 +08:00
aozhiwei
52188b8ada 1 2023-04-24 11:51:40 +08:00
aozhiwei
9ae217eea5 1 2023-04-24 11:42:50 +08:00
aozhiwei
51b01f8e79 1 2023-04-24 11:40:28 +08:00
aozhiwei
4677716f1f 1 2023-04-24 11:34:08 +08:00
aozhiwei
741f5ccdce 1 2023-04-24 11:29:08 +08:00
aozhiwei
0ddb1e12ef 1 2023-04-24 11:19:49 +08:00
aozhiwei
0c1f08b877 1 2023-04-24 11:15:00 +08:00
aozhiwei
39e1c883b6 1 2023-04-24 11:08:56 +08:00
aozhiwei
5ed753636c 1 2023-04-24 11:07:22 +08:00
aozhiwei
54336693e4 1 2023-04-24 11:01:29 +08:00
aozhiwei
6001cb8e02 1 2023-04-24 10:42:53 +08:00
aozhiwei
adeaac6e1d 1 2023-04-24 10:36:42 +08:00
aozhiwei
ff48ed0a67 1 2023-04-24 10:35:53 +08:00
aozhiwei
b5c367d954 1 2023-04-24 10:33:07 +08:00
aozhiwei
8a6b80fa4e 1 2023-04-24 10:26:42 +08:00
aozhiwei
f1e98da3c9 1 2023-04-23 19:37:05 +08:00
aozhiwei
c70cf338be 1 2023-04-23 19:20:33 +08:00
aozhiwei
32076b1c5c 1 2023-04-23 19:14:21 +08:00
aozhiwei
d0c0cabdca 1 2023-04-23 19:10:28 +08:00
aozhiwei
8e251100d2 1 2023-04-23 19:05:03 +08:00
aozhiwei
5447397c21 1 2023-04-23 18:59:57 +08:00
aozhiwei
1279895717 1 2023-04-23 18:55:00 +08:00
aozhiwei
06d1314f29 1 2023-04-23 18:44:57 +08:00
aozhiwei
ba1dc5f3c1 1 2023-04-23 18:39:48 +08:00
aozhiwei
61f2735086 1 2023-04-23 17:58:13 +08:00
aozhiwei
a30e4be78c 1 2023-04-23 17:55:51 +08:00
aozhiwei
97ce74378d 1 2023-04-23 17:52:27 +08:00
aozhiwei
3de96a8575 1 2023-04-23 17:37:09 +08:00
aozhiwei
ed0290f709 1 2023-04-23 17:33:15 +08:00
aozhiwei
71e7af4212 1 2023-04-23 17:19:40 +08:00
aozhiwei
cff0d78fc4 1 2023-04-23 17:17:30 +08:00
aozhiwei
a26e6547cf 1 2023-04-23 16:55:36 +08:00
aozhiwei
7f42fbcd94 1 2023-04-23 16:51:09 +08:00
aozhiwei
4ad5bbdc1e 1 2023-04-23 16:33:44 +08:00
aozhiwei
a968685105 1 2023-04-23 16:07:17 +08:00
aozhiwei
892af52a25 1 2023-04-23 15:45:47 +08:00
azw
1786a4371d 1 2023-04-23 07:30:36 +00:00
azw
70634004d1 1 2023-04-23 03:38:36 +00:00
azw
c23180e417 1 2023-04-22 09:45:12 +00:00
azw
0eb34966e1 1 2023-04-22 09:30:17 +00:00
azw
14beeeeb0c 1 2023-04-22 08:02:31 +00:00
azw
2f5c158c53 1 2023-04-22 07:59:26 +00:00
azw
64d4916dbe 1 2023-04-22 07:55:02 +00:00
azw
851b939da4 1 2023-04-22 07:51:40 +00:00
azw
274d881fee 1 2023-04-22 07:03:34 +00:00
azw
925beb63c9 1 2023-04-22 01:26:18 +00:00
azw
9a4b98738e 1 2023-04-22 01:19:53 +00:00
azw
50f66d54be 1 2023-04-19 03:30:19 +00:00
azw
d5f5b10714 1 2023-04-17 11:41:08 +00:00
azw
393bdfff49 1 2023-04-17 11:02:08 +00:00
azw
10d34b25ce 1 2023-04-17 07:23:00 +00:00
azw
22cc01609a 1 2023-04-17 06:41:19 +00:00
azw
a35add02b6 1 2023-04-17 06:37:54 +00:00
azw
9de27d574f 1 2023-04-17 06:24:32 +00:00
azw
4030f890dc 1 2023-04-17 03:46:34 +00:00
azw
bd8ea9b615 1 2023-04-17 03:24:48 +00:00
azw
27b2cac699 1 2023-04-17 03:21:47 +00:00
azw
8e0bdaca4f 1 2023-04-17 03:05:53 +00:00
azw
2c3eddd247 1 2023-04-17 03:01:43 +00:00
azw
47c546ece5 1 2023-04-17 02:57:52 +00:00
azw
f0e3d861fb 1 2023-04-17 02:56:00 +00:00
azw
e4dc35c2af 1 2023-04-17 02:35:17 +00:00
azw
f856b632ba 1 2023-04-15 09:17:46 +00:00
azw
21d2504eac 1 2023-04-15 09:04:00 +00:00
azw
09ac3bdf20 1 2023-04-15 08:52:40 +00:00
azw
be2e56f589 1 2023-04-15 08:50:40 +00:00
azw
76eb32c357 1 2023-04-15 08:38:03 +00:00
azw
ffa73e12ff 1 2023-04-15 08:00:54 +00:00
azw
fa23c74298 1 2023-04-15 02:12:31 +00:00
azw
332e28cbb8 1 2023-04-14 13:49:41 +00:00
azw
a63c82b677 1 2023-04-14 11:46:55 +00:00
azw
0ff0ffc565 1 2023-04-14 11:31:05 +00:00
azw
f937b70cca 1 2023-04-14 09:48:24 +00:00
azw
48a3cd1cdd 1 2023-04-14 09:28:20 +00:00
azw
895aec82c1 1 2023-04-14 09:13:08 +00:00
azw
057c9b6161 1 2023-04-14 09:10:37 +00:00
azw
ba2151d25c 1 2023-04-14 09:08:57 +00:00
azw
a61719966e 1 2023-04-14 09:00:08 +00:00
azw
9487d93b32 1 2023-04-14 08:41:25 +00:00
azw
7d2535aa39 1 2023-04-14 08:21:49 +00:00
azw
de11de6827 1 2023-04-14 08:17:20 +00:00
azw
6b04c3636e 1 2023-04-14 08:13:50 +00:00
azw
03fdcc6bb7 1 2023-04-14 08:12:07 +00:00
azw
5796e5203e 1 2023-04-14 07:31:49 +00:00
azw
46e42c7228 1 2023-04-14 07:30:32 +00:00
azw
fee8a03cec 1 2023-04-14 07:20:41 +00:00
azw
af9b9d4244 1 2023-04-13 23:45:55 +00:00
azw
c82c77e89a 1 2023-04-13 23:41:30 +00:00
azw
f04a5ec695 1 2023-04-13 23:34:15 +00:00
azw
d577c31664 1 2023-04-13 23:32:02 +00:00
azw
a3a0ad5979 1 2023-04-13 23:08:47 +00:00
azw
7adbdd97bc 1 2023-04-13 23:05:49 +00:00
azw
452f337b9f 1 2023-04-13 23:03:47 +00:00
azw
fb9fefd1aa 1 2023-04-13 22:45:28 +00:00
azw
59b94bced1 1 2023-04-13 22:24:02 +00:00
azw
00606e0349 1 2023-04-13 09:45:11 +00:00
azw
059071f824 1 2023-04-11 13:24:50 +00:00
azw
4c31f2a711 1 2023-04-11 13:21:29 +00:00
azw
6c1441cd8f 1 2023-04-11 13:17:12 +00:00
azw
48fffc757d 1 2023-04-09 12:33:01 +00:00
azw
b1bd720df0 1 2023-04-09 12:24:56 +00:00
azw
a3d545e928 1 2023-04-09 12:23:39 +00:00
azw
306fd4ebfa 1 2023-04-09 12:16:21 +00:00
azw
7e60dc6078 1 2023-04-09 12:08:03 +00:00
azw
179d04da21 1 2023-04-09 09:22:43 +00:00
azw
06cd9f5018 1 2023-04-09 09:14:57 +00:00
azw
71175471e1 1 2023-04-09 08:59:03 +00:00
azw
89816f516a 1 2023-04-09 08:43:13 +00:00
azw
a3bf6bd99d 1 2023-04-09 08:25:56 +00:00
azw
8857b5ab99 1 2023-04-09 08:09:12 +00:00
azw
925f11416a 1 2023-04-09 08:03:10 +00:00
azw
fe7fe5c62e 1 2023-04-09 07:57:31 +00:00
azw
ea3d340cd1 1 2023-04-09 07:44:33 +00:00
azw
efbfca944a 1 2023-04-09 07:42:49 +00:00
azw
0542ded043 1 2023-04-09 07:41:21 +00:00
azw
b5223bdad1 1 2023-04-09 07:39:40 +00:00
azw
5811bcd658 1 2023-04-09 07:35:24 +00:00
azw
8968761471 1 2023-04-09 07:33:02 +00:00
azw
7136a41af6 1 2023-04-09 07:30:42 +00:00
azw
4541b002b2 1 2023-04-09 07:27:47 +00:00
azw
57123819a0 1 2023-04-09 07:25:56 +00:00
azw
dbe993d0ee 1 2023-04-09 07:23:32 +00:00
azw
504964ce43 1 2023-04-09 07:12:17 +00:00
azw
45af072c80 1 2023-04-09 07:05:46 +00:00
azw
5a051c97cc 1 2023-04-09 06:59:55 +00:00
azw
4dbd7177d6 1 2023-04-09 06:55:29 +00:00
azw
3f79474667 1 2023-04-09 06:53:11 +00:00
azw
273b13b018 1 2023-04-09 05:28:55 +00:00
azw
832c134765 1 2023-04-09 05:11:46 +00:00
azw
b941ecdc9b 1 2023-04-09 05:08:17 +00:00
aozhiwei
8504e406e5 1 2022-03-04 16:37:46 +08:00
aozhiwei
58e7d6df7e 移除9003特殊处理 2020-12-28 10:53:17 +08:00
51 changed files with 2071 additions and 1469 deletions

15
.gitmodules vendored
View File

@ -1,9 +1,3 @@
[submodule "third_party/a8engine"]
path = third_party/a8engine
url = git@git.kingsome.cn:server_common/a8engine.git
[submodule "third_party/framework"]
path = third_party/framework
url = git@git.kingsome.cn:server_common/framework.git
[submodule "third_party/tools"]
path = third_party/tools
url = git@git.kingsome.cn:server_common/tools.git
@ -13,3 +7,12 @@
[submodule "third_party/recastnavigation"]
path = third_party/recastnavigation
url = git@git.kingsome.cn:libs/recastnavigation.git
[submodule "third_party/a8"]
path = third_party/a8
url = git@git.kingsome.cn:server_common/a8.git
[submodule "third_party/f8"]
path = third_party/f8
url = git@git.kingsome.cn:server_common/f8.git
[submodule "third_party/kcp"]
path = third_party/kcp
url = git@git.kingsome.cn:libs/kcp.git

View File

@ -10,6 +10,7 @@ enum SSMessageId_e
_SS_MS_ResponseTargetServer = 12;
_SS_ForceCloseSocket = 13;
_SS_CMKcpHandshake = 99;
_SS_CMPing = 101;
_SS_SMRpcError = 102;
_SS_CMLogin = 103;

View File

@ -8,17 +8,42 @@ message SS_CMPing
{
}
message SS_SMPing
{
optional int32 param1 = 1; optional int32 source = 2 [default = 0]; //0:tcp 1:udp
}
message SS_CMLogin_CMReConnect_CommonHead
{
optional int32 server_id = 1;
}
message SS_CMKcpHandshake
{
optional int32 proto_version = 1; //Constant_e.ProtoVersion
optional string account_id = 2; //id
optional string session_id = 3; //session id
optional string team_uuid = 4; //
optional int32 secret_key_place = 5; // 0() 1kcp底层协议头之后()
}
message SS_SMKcpHandshake
{
optional int32 errcode = 1; //errcode != 0kcp
optional string errmsg = 2; //errmsg
optional int32 conv = 3; //conv
optional bytes secret_key = 4; //secret key客户端每次上报的时候加在包头之前
optional string remote_host = 5; //host
optional int32 remote_port = 6; //port
}
message SS_CMLogin
{
optional int32 server_id = 1; //
optional string team_uuid = 2; //
optional string account_id = 3; //id
optional int32 proto_version = 5; //Constant_e.ProtoVersion
optional string session_id = 20; //id
}
message SS_CMReconnect
@ -39,6 +64,9 @@ message SS_WSP_RequestTargetServer
optional string server_info = 4;
optional int32 is_reconnect = 5;
optional int32 proto_version = 6; //Constant_e.ProtoVersion
optional string url = 7;
optional string query_str = 8;
optional string session_id = 9;
}
message SS_MS_ResponseTargetServer

View File

@ -4,23 +4,11 @@ cmake_minimum_required(VERSION 2.8)
if (${GAME_ID})
message(GAME_ID: ${GAME_ID})
else()
set(GAME_ID 1008)
message(GAME_ID: ${GAME_ID})
message(FATAL_ERROR "GAME_ID error")
endif()
if (${MASTER_MODE})
message(MASTER_MODE: 1)
else()
set(MASTER_MODE 0)
message(MASTER_MODE: 0)
endif()
if (${ASYNC_TCPCLIENT})
message(ASYNC_TCPCLIENT: 1)
else()
set(ASYNC_TCPCLIENT 0)
message(ASYNC_TCPCLIENT: 0)
endif()
set(LIB_DIR "ubuntu20.04_g++-9")
message(LIB_DIR: ${LIB_DIR})
if (${RELEASE})
set(CMAKE_BUILD_TYPE "Release")
@ -29,12 +17,18 @@ else()
set(CMAKE_BUILD_TYPE "Debug")
message("debug mode")
endif()
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wall -g -std=gnu++11 -DGAME_ID=${GAME_ID} -DMASTER_MODE=${MASTER_MODE} -DASYNC_TCPCLIENT=${ASYNC_TCPCLIENT} -DNDEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -std=gnu++11 -DGAME_ID=${GAME_ID} -DMASTER_MODE=${MASTER_MODE} -DASYNC_TCPCLIENT=${ASYNC_TCPCLIENT} -DDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wall -g -std=gnu++1z -DGAME_ID=${GAME_ID} -DNDEBUG")
if (${ASAN})
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -std=gnu++1z -DGAME_ID=${GAME_ID} -DDEBUG -fsanitize=address -fno-omit-frame-pointer")
else()
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -std=gnu++1z -DGAME_ID=${GAME_ID} -DDEBUG")
endif()
include_directories(
AFTER
../../third_party/a8engine
../../third_party/a8
../../third_party/f8
/usr/include/mysql
/usr/include/jsoncpp
/usr/include/hiredis
@ -50,14 +44,14 @@ include_directories(
link_directories(
/usr/lib64/mysql
/usr/local/lib
../../third_party/behaviac/lib
../../third_party/behaviac/lib/${LIB_DIR}
)
aux_source_directory(../../third_party/a8engine/a8
aux_source_directory(../../third_party/a8/a8
SRC_LIST
)
aux_source_directory(../../third_party/framework/cpp
aux_source_directory(../../third_party/f8/f8
SRC_LIST
)
@ -94,39 +88,30 @@ add_custom_command(TARGET script_pb_protocol
)
add_dependencies(wsproxy${GAME_ID} script_pb_protocol)
target_link_libraries(
wsproxy${GAME_ID}
pthread
mysqlclient
protobuf
rt
dl
util
crypto
ssl
jsoncpp
curl
hiredis
tinyxml2
)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
target_link_libraries(
wsproxy${GAME_ID}
pthread
mysqlclient
protobuf
rt
dl
util
crypto
ssl
jsoncpp
curl
hiredis
tinyxml2
tcmalloc
behaviac_gcc_debug
)
else()
target_link_libraries(
wsproxy${GAME_ID}
pthread
mysqlclient
protobuf
rt
dl
util
crypto
ssl
jsoncpp
curl
hiredis
tinyxml2
tcmalloc
behaviac_gcc_release
)

View File

@ -1,10 +1,14 @@
#include "precompile.h"
#include <mutex>
#include <google/protobuf/message.h>
#include <a8/websocketsession.h>
#include <a8/tcplistener.h>
#include "framework/cpp/netmsghandler.h"
#include <f8/netmsghandler.h>
#include <f8/udplog.h>
#include <f8/msgqueue.h>
#include "app.h"
#include "GCListener.h"
@ -33,7 +37,8 @@ public:
p->msgid,
p->seqid,
&buf[offset + sizeof(f8::PackHead)],
p->packlen);
p->packlen,
ST_Tcp);
offset += sizeof(f8::PackHead) + p->packlen;
} else {
warning = true;
@ -43,57 +48,61 @@ public:
}
if (warning) {
a8::UdpLog::Instance()->Warning("收到client非法数据包", {});
f8::UdpLog::Instance()->Warning("收到client非法数据包", {});
}
}
virtual void OnRawHttpGet(const std::string& url, const std::string& querystr,
std::string& response) override
{
App::Instance()->AddIMMsg(IM_ExecGM,
a8::XParams()
.SetSender(socket_handle)
.SetParam1(url)
.SetParam2(querystr)
.SetParam3(saddr));
f8::MsgQueue::Instance()->PostMsg
(
IM_ExecGM,
a8::Args
(
{
(int)socket_handle,
(std::string)(url + ""),
(std::string)(querystr + ""),
(unsigned long)saddr
}
)
);
}
virtual bool HandleRedirect(const std::string& url, const std::string& querystr,
std::string& location) override
{
#if MASTER_MODE
a8::HTTPRequest request;
a8::ParserUrlQueryString(querystr.c_str(), request);
if (a8::Get(request, "c").GetString() == "Ops" &&
a8::Get(request, "a").GetString() == "join") {
std::string team_uuid = a8::Get(request, "team_uuid").GetString();
std::vector<std::string> strings;
a8::Split(team_uuid, strings, '_');
if (strings.size() >= 2) {
int node_id = a8::XValue(strings[0]);
if (node_id != App::Instance()->node_id) {
std::string host;
if (JsonDataMgr::Instance()->GetNodeHost(node_id, host)) {
location = a8::Format("wss://%s/webapp/index.php?c=Ops&a=join&team_uuid=%s",
{
host,
team_uuid
});
return true;
}
}
}
}
#ifdef DEBUG
f8::MsgQueue::Instance()->PostMsg
(
IM_HandleRedirect,
a8::Args
(
{
(int)socket_handle,
(std::string)(url + ""),
(std::string)(querystr + ""),
(unsigned long)saddr
}
)
);
#endif
return false;
}
virtual void OnDisConnect() override
{
App::Instance()->AddIMMsg(IM_ClientSocketDisconnect,
a8::XParams()
.SetSender(socket_handle)
.SetParam1(1));
f8::MsgQueue::Instance()->PostMsg
(
IM_ClientSocketDisconnect,
a8::Args
(
{
(int)socket_handle
}
)
);
}
};
@ -105,7 +114,7 @@ static void CreateGameClientSocket(a8::TcpSession **p)
static void GSListeneron_error(a8::TcpListener*, int type, int errorid)
{
a8::UdpLog::Instance()->Debug("GCListeneron_error %d %d", {type, errorid});
f8::UdpLog::Instance()->Debug("GCListeneron_error %d %d", {type, errorid});
}
void GCListener::Init()
@ -117,6 +126,24 @@ void GCListener::Init()
tcp_listener_->bind_address = "0.0.0.0";
tcp_listener_->bind_port = JsonDataMgr::Instance()->GetConf()->At("listen_port")->AsXValue();
tcp_listener_->Open();
f8::MsgQueue::Instance()->RegisterCallBack
(
IM_HandleRedirect,
[this] (const a8::Args& args)
{
int socket_handle = args.Get<int>(0);
std::string url = args.Get<std::string>(1);
std::string query_str = args.Get<std::string>(2);
websocket_url_hash_[socket_handle] = std::make_tuple(url, query_str);
});
f8::MsgQueue::Instance()->RegisterCallBack
(
IM_ClientSocketDisconnect,
[this] (const a8::Args& args)
{
int socket_handle = args.Get<int>(0);
websocket_url_hash_.erase(socket_handle);
});
}
void GCListener::UnInit()
@ -125,21 +152,9 @@ void GCListener::UnInit()
tcp_listener_ = nullptr;
}
void GCListener::ForwardTargetConnMsg(f8::MsgHdr& hdr)
void GCListener::SendBuf(unsigned short sockhandle, char* buf, int buflen)
{
char* buff = (char*)malloc(sizeof(f8::PackHead) + hdr.buflen);
f8::PackHead* head = (f8::PackHead*)buff;
head->packlen = hdr.buflen;
head->msgid = hdr.msgid;
head->seqid = hdr.seqid;
head->magic_code = f8::MAGIC_CODE;
head->ext_len = hdr.buflen >> 16;
if (hdr.buflen > 0) {
memmove(buff + sizeof(f8::PackHead), hdr.buf, hdr.buflen);
}
tcp_listener_->SendClientMsg(hdr.socket_handle, buff, sizeof(f8::PackHead) + head->packlen);
free(buff);
tcp_listener_->SendClientMsg(sockhandle, buf, buflen);
}
void GCListener::SendText(unsigned short sockhandle, const std::string& text)
@ -166,3 +181,20 @@ long long GCListener::GetSentBytesNum()
{
return tcp_listener_->sent_bytes_num;
}
bool GCListener::GetWebSocketUrl(int socket_handle, std::string& url, std::string& query_str)
{
auto itr = websocket_url_hash_.find(socket_handle);
if (itr != websocket_url_hash_.end()) {
url = std::get<0>(itr->second);
query_str = std::get<1>(itr->second);
return true;
} else {
return false;
}
}
int GCListener::GetSocketCount()
{
return tcp_listener_->GetClientSocketCount();
}

View File

@ -23,17 +23,26 @@ class GCListener : public a8::Singleton<GCListener>
void SendMsg(unsigned short socket_handle, T& msg)
{
static int msgid = f8::Net_GetMessageId(msg);
SendMsgEx(socket_handle, msgid, msg);
}
template <typename T>
void SendMsgEx(unsigned short socket_handle, int msgid, T& msg)
{
f8::Net_SendMsg(tcp_listener_, socket_handle, 0, msgid, msg);
}
void ForwardTargetConnMsg(f8::MsgHdr& hdr);
void SendBuf(unsigned short sockhandle, char* buf, int buflen);
void SendText(unsigned short sockhandle, const std::string& text);
void ForceCloseClient(unsigned short sockhandle);
void MarkClient(unsigned short sockhandle, bool is_active);
long long GetSendNodeNum();
long long GetSentBytesNum();
bool GetWebSocketUrl(int socket_handle, std::string& url, std::string& query_str);
int GetSocketCount();
private:
private:
a8::TcpListener *tcp_listener_ = nullptr;
std::map<int, std::tuple<std::string, std::string>> websocket_url_hash_;
};

View File

@ -6,29 +6,31 @@
#include <mutex>
#include <condition_variable>
#include <a8/redis.h>
#include <a8/timer.h>
#include <a8/xtimer.h>
#include <a8/uuid.h>
#include <a8/ioloop.h>
#include <a8/udplistener.h>
#include "framework/cpp/netmsghandler.h"
#include <f8/netmsghandler.h>
#include <f8/udplog.h>
#include <f8/msgqueue.h>
#include "app.h"
#include "GCListener.h"
#include "jsondatamgr.h"
#include "handlermgr.h"
#include "gameclient.h"
#include "gameclientmgr.h"
#include "downstream.h"
#include "downstreammgr.h"
#include "upstream.h"
#include "upstreammgr.h"
#include "master.h"
#include "mastermgr.h"
#include "longsessionmgr.h"
#include "ss_msgid.pb.h"
#include "ss_proto.pb.h"
#include "target_conn.h"
#include "target_conn_mgr.h"
#if MASTER_MODE
#include "mastersvr.h"
#include "mastersvrmgr.h"
#endif
struct MsgNode
{
SocketFrom_e sockfrom;
@ -38,15 +40,14 @@ struct MsgNode
long ip_saddr;
char* buf;
int buflen;
int tag;
MsgNode* next;
};
struct IMMsgNode
struct UdpMsgNode
{
unsigned short msgid;
a8::XParams params;
IMMsgNode* next = nullptr;
a8::UdpPacket* pkt;
UdpMsgNode* next;
};
const char* const PROJ_LOG_ROOT_FMT = "/data/logs/%s/logs";
@ -54,193 +55,170 @@ const char* const PROJ_LOG_FILENAME_FMT = "log_$pid_%Y%m%d.log";
static void SavePerfLog()
{
a8::UdpLog::Instance()->Info(" max_run_delay_time:%d max_timer_idle:%d "
"in_data_size:%d out_data_size:%d msgnode_size:%d read_count:%d max_login_time:%d "
"max_join_time:%d",
f8::UdpLog::Instance()->Info("max_run_delay_time:%d max_timer_idle:%d "
"in_data_size:%d out_data_size:%d msgnode_size:%d udp_msgnode_size:%d "
"read_count:%d max_login_time:%d "
"max_join_time:%d tcp_count:%d udp_count:%d down_stream_count:%d",
{
App::Instance()->perf.max_run_delay_time,
App::Instance()->perf.max_timer_idle,
App::Instance()->perf.in_data_size,
App::Instance()->perf.out_data_size,
App::Instance()->msgnode_size_,
App::Instance()->perf.read_count,
App::Instance()->perf.max_login_time,
App::Instance()->perf.max_join_time,
App::Instance()->GetPerf().max_run_delay_time,
App::Instance()->GetPerf().max_timer_idle,
App::Instance()->GetPerf().in_data_size,
App::Instance()->GetPerf().out_data_size,
App::Instance()->GetMsgNodeSize(),
App::Instance()->GetUdpMsgNodeSize(),
App::Instance()->GetPerf().read_count,
App::Instance()->GetPerf().max_login_time,
App::Instance()->GetPerf().max_join_time,
GCListener::Instance()->GetSocketCount(),
LongSessionMgr::Instance()->GetLongSessionCount(),
DownStreamMgr::Instance()->GetDownStreamCount()
});
#if ASYNC_TCPCLIENT && GAME_ID == 2002
a8::UdpLog::Instance()->Info(" run_times:%d timer_times:%d event_times:%d free_times:%d "
" shutdown_times:%d connect_times:%d close_times:%d "
" send_times:%d recv_times:%d error_times:%d immsg_times:%d",
{
(long long)a8::IoLoop::Instance()->run_times,
(long long)a8::IoLoop::Instance()->timer_times,
(long long)a8::IoLoop::Instance()->event_times,
(long long)a8::IoLoop::Instance()->free_times,
(long long)a8::IoLoop::Instance()->shutdown_times,
(long long)a8::IoLoop::Instance()->connect_times,
(long long)a8::IoLoop::Instance()->close_times,
(long long)a8::IoLoop::Instance()->send_times,
(long long)a8::IoLoop::Instance()->recv_times,
(long long)a8::IoLoop::Instance()->error_times,
(long long)a8::IoLoop::Instance()->immsg_times
});
#endif
if (App::Instance()->HasFlag(2)) {
a8::XPrintf("mainloop_time:%d netmsg_time:%d send_node_num:%d sent_bytes_num:%d\n",
{
App::Instance()->perf.max_run_delay_time,
App::Instance()->perf.max_dispatchmsg_time,
App::Instance()->GetPerf().max_run_delay_time,
App::Instance()->GetPerf().max_dispatchmsg_time,
GCListener::Instance()->GetSendNodeNum(),
GCListener::Instance()->GetSentBytesNum()
});
}
#if 1
App::Instance()->perf.max_run_delay_time = 0;
App::Instance()->perf.max_timer_idle = 0;
App::Instance()->perf.max_login_time = 0;
App::Instance()->perf.max_join_time = 0;
#else
App::Instance()->perf = PerfMonitor();
#endif
App::Instance()->GetPerf().max_run_delay_time = 0;
App::Instance()->GetPerf().max_timer_idle = 0;
App::Instance()->GetPerf().max_login_time = 0;
App::Instance()->GetPerf().max_join_time = 0;
}
bool App::Init(int argc, char* argv[])
{
signal(SIGPIPE, SIG_IGN);
this->argc = argc;
this->argv = argv;
this->argc_ = argc;
this->argv_ = argv;
if (!ParseOpt()) {
terminated = true;
#if MASTER_MODE
if (node_id <= 0) {
terminated_ = true;
if (node_id_ <= 0) {
a8::XPrintf("gameserver启动失败,缺少-n参数\n", {});
} else if (node_id > MAX_NODE_ID) {
} else if (node_id_ > MAX_NODE_ID) {
a8::XPrintf("gameserver启动失败,-n参数不能大于%d\n", {MAX_NODE_ID});
} else if (instance_id <= 0) {
} else if (instance_id_ <= 0) {
a8::XPrintf("gameserver启动失败,缺少-i参数\n", {});
} else if (instance_id > MAX_INSTANCE_ID) {
} else if (instance_id_ > MAX_INSTANCE_ID) {
a8::XPrintf("gameserver启动失败,-i参数不能大于%d\n", {MAX_INSTANCE_ID});
}
#else
a8::XPrintf("wsproxy启动失败,缺少-i参数\n", {});
#endif
return false;
}
a8::XPrintf("wsproxy starting node_id:%d instance_id:%d pid:%d master_mode:%d async_tcpclient:%d\n",
a8::XPrintf("wsproxy starting node_id:%d instance_id:%d pid:%d\n",
{
node_id,
instance_id,
getpid(),
MASTER_MODE,
ASYNC_TCPCLIENT
node_id_,
instance_id_,
getpid()
});
uuid_ = std::make_shared<a8::uuid::SnowFlake>();
loop_mutex_ = new std::mutex();
loop_cond_ = new std::condition_variable();
msg_mutex_ = new std::mutex();
im_msg_mutex_ = new std::mutex();
udp_msg_mutex_ = new std::mutex();
srand(time(nullptr));
InitLog();
f8::MsgQueue::Instance()->Init();
HandlerMgr::Instance()->Init();
a8::Timer::Instance()->Init();
a8::IoLoop::Instance()->Init(1);
f8::Timer::Instance()->Init();
JsonDataMgr::Instance()->Init();
#if MASTER_MODE
uuid.SetMachineId((node_id - 1) * MAX_NODE_ID + instance_id);
#else
uuid.SetMachineId(instance_id);
#endif
GameClientMgr::Instance()->Init();
#if MASTER_MODE
MasterSvrMgr::Instance()->Init();
#endif
TargetConnMgr::Instance()->Init();
uuid_->SetMachineId((node_id_ - 1) * MAX_NODE_ID + instance_id_);
DownStreamMgr::Instance()->Init();
MasterMgr::Instance()->Init();
UpStreamMgr::Instance()->Init();
LongSessionMgr::Instance()->Init();
GCListener::Instance()->Init();
a8::UdpLog::Instance()->Info("wsproxy starting instance_id:%d pid:%d async_tcpclient:%d",
f8::UdpLog::Instance()->Info("wsproxy starting instance_id:%d pid:%d",
{
instance_id,
instance_id_,
getpid(),
ASYNC_TCPCLIENT
});
{
int perf_log_time = 1000 * 60 * 5;
if (getenv("is_dev_env")) {
perf_log_time = 1000 * 10;
}
a8::Timer::Instance()->AddRepeatTimer(perf_log_time,
a8::XParams(),
[] (const a8::XParams& param)
{
SavePerfLog();
});
f8::Timer::Instance()->SetInterval
(perf_log_time,
[] (int event, const a8::Args* args)
{
if (a8::TIMER_EXEC_EVENT == event) {
SavePerfLog();
}
});
}
if (HasFlag(1)) {
a8::Timer::Instance()->AddDeadLineTimer(
1000 * 60,
a8::XParams(),
[] (const a8::XParams& param)
{
App::Instance()->terminated = true;
App::Instance()->NotifyLoopCond();
}
);
f8::Timer::Instance()->SetTimeout
(
1000 * 60,
[] (int event, const a8::Args* args)
{
if (a8::TIMER_EXEC_EVENT == event) {
App::Instance()->terminated_ = true;
App::Instance()->NotifyLoopCond();
}
}
);
}
if (HasFlag(4)) {
a8::Timer::Instance()->AddDeadLineTimer(
1000 * 30,
a8::XParams(),
[] (const a8::XParams& param)
{
App::Instance()->shutdowned = true;
a8::XPrintf("shutdowned\n", {});
}
);
f8::Timer::Instance()->SetTimeout
(
1000 * 30,
[] (int event, const a8::Args* args)
{
if (a8::TIMER_EXEC_EVENT == event) {
App::Instance()->shutdowned_ = true;
a8::XPrintf("shutdowned\n", {});
}
}
);
}
return true;
}
void App::UnInit()
{
a8::XPrintf("wsproxy terminating instance_id:%d pid:%d\n", {instance_id, getpid()});
a8::XPrintf("wsproxy terminating instance_id:%d pid:%d\n", {instance_id_, getpid()});
GCListener::Instance()->UnInit();
#if MASTER_MODE
MasterSvrMgr::Instance()->UnInit();
#endif
TargetConnMgr::Instance()->UnInit();
GameClientMgr::Instance()->UnInit();
LongSessionMgr::Instance()->UnInit();
MasterMgr::Instance()->UnInit();
UpStreamMgr::Instance()->UnInit();
DownStreamMgr::Instance()->UnInit();
JsonDataMgr::Instance()->UnInit();
a8::IoLoop::Instance()->UnInit();
a8::Timer::Instance()->UnInit();
f8::Timer::Instance()->UnInit();
f8::MsgQueue::Instance()->UnInit();
HandlerMgr::Instance()->UnInit();
UnInitLog();
FreeSocketMsgQueue();
FreeIMMsgQueue();
delete im_msg_mutex_;
im_msg_mutex_ = nullptr;
FreeUdpMsgQueue();
delete msg_mutex_;
msg_mutex_ = nullptr;
delete udp_msg_mutex_;
udp_msg_mutex_ = nullptr;
delete loop_cond_;
loop_cond_ = nullptr;
delete loop_mutex_;
loop_mutex_ = nullptr;
a8::XPrintf("wsproxy terminated instance_id:%d pid:%d\n", {instance_id, getpid()});
a8::XPrintf("wsproxy terminated instance_id:%d pid:%d\n", {instance_id_, getpid()});
}
int App::Run()
{
int ret = 0;
a8::UdpLog::Instance()->Info("wsproxy running", {});
while (!terminated) {
f8::UdpLog::Instance()->Info("wsproxy running", {});
while (!terminated_) {
a8::tick_t begin_tick = a8::XGetTickCount();
QuickExecute();
SlowerExecute();
a8::tick_t end_tick = a8::XGetTickCount();
if (end_tick - begin_tick > perf.max_run_delay_time) {
perf.max_run_delay_time = end_tick - begin_tick;
if (end_tick - begin_tick > GetPerf().max_run_delay_time) {
GetPerf().max_run_delay_time = end_tick - begin_tick;
}
Schedule();
}
@ -253,9 +231,10 @@ void App::AddSocketMsg(SocketFrom_e sockfrom,
unsigned short msgid,
unsigned int seqid,
const char *msgbody,
int bodylen)
int bodylen,
int tag)
{
MsgNode *p = (MsgNode*) malloc(sizeof(MsgNode));
MsgNode *p = (MsgNode*)malloc(sizeof(MsgNode));
memset(p, 0, sizeof(MsgNode));
p->sockfrom = sockfrom;
p->ip_saddr = ip_saddr;
@ -264,6 +243,7 @@ void App::AddSocketMsg(SocketFrom_e sockfrom,
p->seqid = seqid;
p->buf = nullptr;
p->buflen = bodylen;
p->tag = tag;
if (bodylen > 0) {
p->buf = (char*)malloc(bodylen);
memmove(p->buf, msgbody, bodylen);
@ -281,29 +261,13 @@ void App::AddSocketMsg(SocketFrom_e sockfrom,
NotifyLoopCond();
}
void App::AddIMMsg(unsigned short imcmd, a8::XParams params)
{
IMMsgNode *p = new IMMsgNode;
p->msgid = imcmd;
p->params = params;
p->next = nullptr;
im_msg_mutex_->lock();
if (im_bot_node_) {
im_bot_node_->next = p;
im_bot_node_ = p;
} else {
im_top_node_ = p;
im_bot_node_ = p;
}
im_msg_mutex_->unlock();
NotifyLoopCond();
}
void App::QuickExecute()
{
ProcessIMMsg();
f8::Timer::Instance()->Update();
f8::MsgQueue::Instance()->Update();
DispatchMsg();
a8::Timer::Instance()->Update();
DispatchUdpMsg();
LongSessionMgr::Instance()->Update();
}
void App::SlowerExecute()
@ -320,30 +284,21 @@ void App::Schedule()
{
std::unique_lock<std::mutex> lk(*loop_mutex_);
if (!HasTask()) {
int sleep_time = a8::Timer::Instance()->GetIdleableMillSeconds();
#if 1
int sleep_time = 1;
loop_cond_->wait_for(lk, std::chrono::milliseconds(sleep_time));
#else
int sleep_time = f8::Timer::Instance()->GetIdleableMillSeconds();
loop_cond_->wait_for(lk, std::chrono::milliseconds(sleep_time));
if (sleep_time > perf.max_timer_idle) {
perf.max_timer_idle = sleep_time;
}
#endif
}
}
bool App::HasTask()
{
{
if (!im_work_node_) {
im_msg_mutex_->lock();
if (!im_work_node_ && im_top_node_) {
im_work_node_ = im_top_node_;
im_top_node_ = nullptr;
im_bot_node_ = nullptr;
}
im_msg_mutex_->unlock();
}
if (im_work_node_) {
return true;
}
}
{
if (!work_node_) {
msg_mutex_->lock();
@ -358,6 +313,20 @@ bool App::HasTask()
return true;
}
}
{
if (!udp_work_node_) {
udp_msg_mutex_->lock();
if (!udp_work_node_ && udp_top_node_) {
udp_work_node_ = udp_top_node_;
udp_top_node_ = nullptr;
udp_bot_node_ = nullptr;
}
udp_msg_mutex_->unlock();
}
if (udp_work_node_) {
return true;
}
}
return false;
}
@ -387,17 +356,17 @@ void App::DispatchMsg()
switch (pdelnode->sockfrom) {
case SF_Client:
{
ProcessClientMsg(hdr);
ProcessClientMsg(hdr, pdelnode->tag);
}
break;
case SF_TargetServer:
{
ProcessTargetServerMsg(hdr);
ProcessTargetServerMsg(hdr, pdelnode->tag);
}
break;
case SF_MasterServer:
{
ProcessMasterServerMsg(hdr);
ProcessMasterServerMsg(hdr, pdelnode->tag);
}
break;
}
@ -416,27 +385,27 @@ void App::DispatchMsg()
}
}
void App::ProcessClientMsg(f8::MsgHdr& hdr)
void App::ProcessClientMsg(f8::MsgHdr& hdr, int tag)
{
if (hdr.msgid < 100) {
return;
}
#if MASTER_MODE
if (hdr.msgid == ss::_SS_CMLogin || hdr.msgid == ss::_SS_CMReconnect) {
GameClient* client = GameClientMgr::Instance()->GetGameClientBySocket(hdr.socket_handle);
if (!client) {
if (hdr.msgid == ss::_SS_CMLogin ||
hdr.msgid == ss::_SS_CMReconnect ||
hdr.msgid == ss::_SS_CMKcpHandshake) {
auto down_wp = DownStreamMgr::Instance()->GetDownStream(hdr.socket_handle);
if (down_wp.expired()) {
switch (hdr.msgid) {
case ss::_SS_CMLogin:
{
ss::SS_CMLogin msg;
bool ok = msg.ParseFromArray(hdr.buf + hdr.offset, hdr.buflen - hdr.offset);
if (ok) {
MasterSvrMgr::Instance()->RequestTargetServer(hdr,
msg.team_uuid(),
msg.account_id(),
"",
0,
msg.proto_version());
MasterMgr::Instance()->RequestTargetServer
(hdr,
msg.team_uuid(),
msg.account_id(),
msg.session_id(),
"",
0,
msg.proto_version());
}
}
break;
@ -445,136 +414,67 @@ void App::ProcessClientMsg(f8::MsgHdr& hdr)
ss::SS_CMReconnect msg;
bool ok = msg.ParseFromArray(hdr.buf + hdr.offset, hdr.buflen - hdr.offset);
if (ok) {
MasterSvrMgr::Instance()->RequestTargetServer(hdr,
msg.team_uuid(),
msg.account_id(),
msg.server_info(),
1,
0);
MasterMgr::Instance()->RequestTargetServer
(hdr,
msg.team_uuid(),
msg.account_id(),
msg.session_id(),
msg.server_info(),
1,
0);
}
}
break;
case ss::_SS_CMKcpHandshake:
{
ss::SS_CMKcpHandshake msg;
bool ok = msg.ParseFromArray(hdr.buf + hdr.offset, hdr.buflen - hdr.offset);
if (ok) {
LongSessionMgr::Instance()->_SS_CMKcpHandshake(hdr, msg);
}
}
break;
default:
{
#if 0
abort();
#endif
}
break;
}
}
} else {
GameClient* client = GameClientMgr::Instance()->GetGameClientBySocket(hdr.socket_handle);
if (client && client->conn) {
if (client->conn) {
client->conn->ForwardClientMsg(hdr);
}
auto down_wp = DownStreamMgr::Instance()->GetDownStream(hdr.socket_handle);
if (auto down = down_wp.lock(); !down_wp.expired()) {
down->ProcCMMsg(hdr, tag);
}
}
#else
TargetConn* conn = nullptr;
if (hdr.msgid == ss::_SS_CMLogin || hdr.msgid == ss::_SS_CMReConnect) {
ss::SS_CMLogin_CMReConnect_CommonHead msg;
bool ok = msg.ParseFromArray(hdr.buf + hdr.offset, hdr.buflen - hdr.offset);
if (ok) {
conn = TargetConnMgr::Instance()->GetConnById(msg.server_id());
if (!conn) {
ss::SS_SMRpcError respmsg;
respmsg.set_error_code(10);
GCListener::Instance()->SendMsg(hdr.socket_handle, respmsg);
}
} else {
return;
}
} else {
GameClient* client = GameClientMgr::Instance()->GetGameClientBySocket(hdr.socket_handle);
if (client) {
conn = client->conn;
}
}
if (conn) {
conn->ForwardClientMsg(hdr);
}
#endif
}
void App::ProcessMasterServerMsg(f8::MsgHdr& hdr)
void App::ProcessMasterServerMsg(f8::MsgHdr& hdr, int tag)
{
#if MASTER_MODE
f8::NetMsgHandler* handler = f8::GetNetMsgHandler(&HandlerMgr::Instance()->msmsghandler,
hdr.msgid);
if (handler) {
switch (handler->handlerid) {
case HID_MasterSvrMgr:
ProcessNetMsg(handler, MasterSvrMgr::Instance(), hdr);
case HID_MasterMgr:
ProcessNetMsg(handler, MasterMgr::Instance(), hdr);
break;
}
}
#endif
}
void App::ProcessTargetServerMsg(f8::MsgHdr& hdr)
void App::ProcessTargetServerMsg(f8::MsgHdr& hdr, int tag)
{
if (hdr.msgid == ss::_SS_ForceCloseSocket) {
GCListener::Instance()->ForceCloseClient(hdr.socket_handle);
return;
}
if (hdr.msgid < 100) {
return;
}
if (hdr.msgid == ss::_SS_CMLogin || hdr.msgid == ss::_SS_CMReconnect) {
GameClientMgr::Instance()->BindTargetConn(hdr.socket_handle, hdr.ip_saddr);
DownStreamMgr::Instance()->BindUpStream(hdr.socket_handle, hdr.ip_saddr);
GCListener::Instance()->MarkClient(hdr.socket_handle, true);
}
GCListener::Instance()->ForwardTargetConnMsg(hdr);
}
void App::ProcessIMMsg()
{
if (!im_work_node_ && im_top_node_) {
im_msg_mutex_->lock();
im_work_node_ = im_top_node_;
im_top_node_ = nullptr;
im_bot_node_ = nullptr;
im_msg_mutex_->unlock();
}
while (im_work_node_) {
IMMsgNode *pdelnode = im_work_node_;
switch (im_work_node_->msgid) {
case IM_ClientSocketDisconnect:
{
GameClientMgr::Instance()->OnClientDisconnect(pdelnode->params);
#if MASTER_MODE
MasterSvrMgr::Instance()->RemoveRequest(pdelnode->params.param1, pdelnode->params.sender, true);
#endif
}
break;
case IM_TargetConnConnect:
{
GameClientMgr::Instance()->OnTargetServerConnect(pdelnode->params);
TargetConn* conn = TargetConnMgr::Instance()->GetConnById(pdelnode->params.sender);
if (conn && conn->Connected()) {
conn->SendStockMsg();
}
}
break;
case IM_TargetConnDisconnect:
{
GameClientMgr::Instance()->OnTargetServerDisconnect(pdelnode->params);
}
break;
case IM_ExecGM:
{
HandlerMgr::Instance()->ProcGMMsg(pdelnode->params.param3,
pdelnode->params.sender,
pdelnode->params.param1.GetString(),
pdelnode->params.param2.GetString()
);
}
break;
}
im_work_node_ = im_work_node_->next;
delete pdelnode;
auto down_wp = DownStreamMgr::Instance()->GetDownStream(hdr.socket_handle);
if (!down_wp.expired()) {
down_wp.lock()->ForwardUpStreamMsg(hdr);
}
}
@ -590,31 +490,31 @@ void App::InitLog()
a8::MkDir(proj_root_dir);
a8::MkDir(proj_log_root_dir);
a8::UdpLog::Instance()->SetLogFileName(log_file_name);
a8::UdpLog::Instance()->Init();
a8::UdpLog::Instance()->Info("proj_root_dir:%s", {proj_root_dir});
a8::UdpLog::Instance()->Info("proj_log_root_dir:%s", {proj_log_root_dir});
a8::UdpLog::Instance()->Info("log_file_name:%s", {log_file_name});
f8::UdpLog::Instance()->SetLogFileName(log_file_name);
f8::UdpLog::Instance()->Init();
f8::UdpLog::Instance()->Info("proj_root_dir:%s", {proj_root_dir});
f8::UdpLog::Instance()->Info("proj_log_root_dir:%s", {proj_log_root_dir});
f8::UdpLog::Instance()->Info("log_file_name:%s", {log_file_name});
}
void App::UnInitLog()
{
a8::UdpLog::Instance()->UnInit();
f8::UdpLog::Instance()->UnInit();
}
bool App::ParseOpt()
{
int ch = 0;
while ((ch = getopt(argc, argv, "n:i:f:")) != -1) {
while ((ch = getopt(argc_, argv_, "n:i:f:")) != -1) {
switch (ch) {
case 'n':
{
node_id = a8::XValue(optarg);
node_id_ = a8::XValue(optarg);
}
break;
case 'i':
{
instance_id = a8::XValue(optarg);
instance_id_ = a8::XValue(optarg);
}
break;
case 'f':
@ -622,39 +522,18 @@ bool App::ParseOpt()
std::vector<std::string> strings;
a8::Split(optarg, strings, ',');
for (auto& str : strings) {
flags.insert(a8::XValue(str).GetInt());
flags_.insert(a8::XValue(str).GetInt());
}
}
break;
}
}
#if MASTER_MODE
return instance_id > 0 && node_id > 0;
#else
return instance_id > 0;
#endif
}
a8::XParams* App::AddContext(long long context_id)
{
context_hash_[context_id] = a8::XParams();
return GetContext(context_id);
}
void App::DelContext(long long context_id)
{
context_hash_.erase(context_id);
}
a8::XParams* App::GetContext(long long context_id)
{
auto itr = context_hash_.find(context_id);
return itr != context_hash_.end() ? &(itr->second) : nullptr;
return instance_id_ > 0 && node_id_ > 0;
}
bool App::HasFlag(int flag)
{
return flags.find(flag) != flags.end();
return flags_.find(flag) != flags_.end();
}
void App::FreeSocketMsgQueue()
@ -681,27 +560,86 @@ void App::FreeSocketMsgQueue()
msg_mutex_->unlock();
}
void App::FreeIMMsgQueue()
void App::FreeUdpMsgQueue()
{
im_msg_mutex_->lock();
if (!im_work_node_) {
im_work_node_ = im_top_node_;
im_top_node_ = nullptr;
im_bot_node_ = nullptr;
udp_msg_mutex_->lock();
if (!udp_work_node_) {
udp_work_node_ = udp_top_node_;
udp_top_node_ = nullptr;
udp_bot_node_ = nullptr;
}
while (im_work_node_) {
IMMsgNode* pdelnode = im_work_node_;
im_work_node_ = im_work_node_->next;
if (pdelnode->msgid == f8::IM_SysMsgQueue) {
a8::XParams* param = (a8::XParams*)pdelnode->params.param1.GetUserData();
delete param;
while (udp_work_node_) {
UdpMsgNode* pdelnode = udp_work_node_;
udp_work_node_ = udp_work_node_->next;
{
if (pdelnode->pkt->buf) {
free((void*)pdelnode->pkt->buf);
}
delete pdelnode->pkt;
free(pdelnode);
}
delete pdelnode;
if (!im_work_node_) {
im_work_node_ = im_top_node_;
im_top_node_ = nullptr;
im_bot_node_ = nullptr;
if (!udp_work_node_) {
udp_work_node_ = udp_top_node_;
udp_top_node_ = nullptr;
udp_bot_node_ = nullptr;
}
}
im_msg_mutex_->unlock();
udp_msg_mutex_->unlock();
}
void App::AddUdpMsg(a8::UdpPacket* pkt)
{
UdpMsgNode *p = (UdpMsgNode*) malloc(sizeof(UdpMsgNode));
memset(p, 0, sizeof(UdpMsgNode));
p->pkt = pkt;
udp_msg_mutex_->lock();
if (udp_bot_node_) {
udp_bot_node_->next = p;
udp_bot_node_ = p;
} else {
udp_top_node_ = p;
udp_bot_node_ = p;
}
++udp_msgnode_size_;
udp_msg_mutex_->unlock();
NotifyLoopCond();
}
void App::DispatchUdpMsg()
{
long long starttick = a8::XGetTickCount();
if (!udp_work_node_ && udp_top_node_) {
udp_msg_mutex_->lock();
udp_work_node_ = udp_top_node_;
udp_top_node_ = nullptr;
udp_bot_node_ = nullptr;
udp_working_msgnode_size_ = udp_msgnode_size_;
udp_msg_mutex_->unlock();
}
while (udp_work_node_) {
UdpMsgNode *pdelnode = udp_work_node_;
LongSessionMgr::Instance()->ProcUdpPacket(pdelnode->pkt);
udp_work_node_ = pdelnode->next;
{
if (pdelnode->pkt->buf) {
free((void*)pdelnode->pkt->buf);
}
delete pdelnode->pkt;
free(pdelnode);
}
udp_working_msgnode_size_--;
if (a8::XGetTickCount() - starttick > 200) {
break;
}
}//end while
if (!udp_work_node_) {
udp_working_msgnode_size_ = 0;
}
}
long long App::NewUuid()
{
return uuid_->Generate();
}

View File

@ -1,16 +1,25 @@
#pragma once
#include <a8/uuid.h>
#include <a8/singleton.h>
namespace a8
{
struct UdpPacket;
namespace uuid
{
class SnowFlake;
}
}
struct MsgNode;
struct IMMsgNode;
struct UdpMsgNode;
class App : public a8::Singleton<App>
{
private:
private:
App() {};
friend class a8::Singleton<App>;
public:
public:
bool Init(int argc, char* argv[]);
void UnInit();
@ -23,15 +32,19 @@ class App : public a8::Singleton<App>
unsigned short msgid,
unsigned int seqid,
const char *msgbody,
int bodylen);
void AddIMMsg(unsigned short imcmd, a8::XParams params);
int bodylen,
int tag = ST_Tcp);
void AddUdpMsg(a8::UdpPacket* pkt);
void NotifyLoopCond();
a8::XParams* AddContext(long long context_id);
void DelContext(long long context_id);
a8::XParams* GetContext(long long context_id);
bool HasFlag(int flag);
long long NewUuid();
int GetNodeId() { return node_id_; }
int GetInstanceId() { return instance_id_; }
PerfMonitor& GetPerf() { return perf_; }
int GetMsgNodeSize() { return msgnode_size_;}
int GetUdpMsgNodeSize() { return udp_msgnode_size_;}
private:
void QuickExecute();
@ -40,50 +53,47 @@ private:
bool HasTask();
void DispatchMsg();
void ProcessIMMsg();
void DispatchUdpMsg();
void ProcessClientMsg(f8::MsgHdr& hdr);
void ProcessMasterServerMsg(f8::MsgHdr& hdr);
void ProcessTargetServerMsg(f8::MsgHdr& hdr);
void ProcessClientMsg(f8::MsgHdr& hdr, int tag);
void ProcessMasterServerMsg(f8::MsgHdr& hdr, int tag);
void ProcessTargetServerMsg(f8::MsgHdr& hdr, int tag);
void InitLog();
void UnInitLog();
bool ParseOpt();
void FreeSocketMsgQueue();
void FreeIMMsgQueue();
void FreeUdpMsgQueue();
public:
int argc = 0;
char** argv = nullptr;
volatile bool terminated = false;
volatile bool shutdowned = false;
std::set<int> flags;
PerfMonitor perf;
a8::uuid::SnowFlake uuid;
private:
int argc_ = 0;
char** argv_ = nullptr;
PerfMonitor perf_;
volatile bool terminated_ = false;
volatile bool shutdowned_ = false;
public:
int node_id = 0;
int instance_id = 0;
int node_id_ = 0;
int instance_id_ = 0;
std::set<int> flags_;
private:
std::shared_ptr<a8::uuid::SnowFlake> uuid_;
std::mutex *loop_mutex_ = nullptr;
std::condition_variable *loop_cond_ = nullptr;
std::mutex *msg_mutex_ = nullptr;
std::mutex* msg_mutex_ = nullptr;
MsgNode* top_node_ = nullptr;
MsgNode* bot_node_ = nullptr;
MsgNode* work_node_ = nullptr;
std::mutex* im_msg_mutex_ = nullptr;
IMMsgNode* im_top_node_ = nullptr;
IMMsgNode* im_bot_node_ = nullptr;
IMMsgNode* im_work_node_ = nullptr;
std::mutex* udp_msg_mutex_ = nullptr;
UdpMsgNode* udp_top_node_ = nullptr;
UdpMsgNode* udp_bot_node_ = nullptr;
UdpMsgNode* udp_work_node_ = nullptr;
std::map<long long, a8::XParams> context_hash_;
public:
int msgnode_size_ = 0 ;
int udp_msgnode_size_ = 0 ;
int working_msgnode_size_ = 0;
int udp_working_msgnode_size_ = 0;
};

View File

@ -7,37 +7,33 @@ enum SocketFrom_e
SF_MasterServer,
};
enum SocketTag_e
{
ST_Tcp = 1,
ST_Udp,
};
enum InnerMesssage_e
{
IM_ClientSocketDisconnect = 100,
IM_PlayerOffline,
IM_ExecGM,
IM_TargetConnDisconnect,
IM_MasterSvrDisconnect,
IM_TargetConnConnect,
IM_UpStreamDisconnect,
IM_UpStreamConnect,
IM_HandleRedirect
};
//网络处理对象
enum NetHandler_e
{
HID_GCListener,
HID_MasterSvrMgr,
};
enum PlayerState_e
{
PS_None,
PS_InRoom,
PS_Matching,
PS_WaitingMatch
HID_MasterMgr,
};
const char* const PROJ_NAME_FMT = "game%d_wsproxy";
const char* const PROJ_ROOT_FMT = "/data/logs/%s";
const int POSTFIX_LEN = 7;
const int MAX_NODE_ID = 8;
const int MAX_INSTANCE_ID = 500;
const char* const azw_account_id = "6001_2001_oJqfX5c4pvW-wlarmcrvEO6BQjd8";
const int ALLOC_TARGET_SERVER_SUCCESS_TIMER_EVENT = a8::TIMER_USER_EVENT + 1;

View File

@ -0,0 +1,89 @@
#include "precompile.h"
#include "downstream.h"
#include "upstream.h"
#include "longsessionmgr.h"
#include "GCListener.h"
#include "longsession.h"
#include "kcpsession.h"
#include "ss_msgid.pb.h"
#include "ss_proto.pb.h"
void DownStream::Init(int socket_handle, std::weak_ptr<UpStream> up)
{
socket_handle_ = socket_handle;
up_ = up;
long_session_wp_ = LongSessionMgr::Instance()->GetSession(socket_handle_);
is_long_session_ = !long_session_wp_.expired();
}
void DownStream::ReBindUpStream(std::weak_ptr<UpStream> up)
{
up_ = up;
}
void DownStream::ForwardUpStreamMsg(f8::MsgHdr& hdr)
{
char* buff = (char*)malloc(sizeof(f8::PackHead) + hdr.buflen);
f8::PackHead* head = (f8::PackHead*)buff;
head->packlen = hdr.buflen;
head->msgid = hdr.msgid;
head->seqid = hdr.seqid;
head->magic_code = f8::MAGIC_CODE;
head->ext_len = hdr.buflen >> 16;
if (hdr.buflen > 0) {
memmove(buff + sizeof(f8::PackHead), hdr.buf, hdr.buflen);
}
if (auto long_session = long_session_wp_.lock(); !long_session_wp_.expired()) {
if (hdr.msgid == ss::_SS_CMPing) {
ss::SS_SMPing msg;
msg.set_source(1);
{
free(buff);
buff = (char*)malloc(sizeof(f8::PackHead) + msg.ByteSize());
f8::PackHead* head = (f8::PackHead*)buff;
head->packlen = msg.ByteSize();
head->msgid = hdr.msgid;
head->seqid = hdr.seqid;
head->magic_code = f8::MAGIC_CODE;
head->ext_len = hdr.buflen >> 16;
msg.SerializeToArray(buff + sizeof(f8::PackHead), head->packlen);
long_session->GetKcpSession()->SendClientMsg(buff, sizeof(f8::PackHead) + head->packlen);
}
} else {
long_session->GetKcpSession()->SendClientMsg(buff, sizeof(f8::PackHead) + head->packlen);
}
} else {
GCListener::Instance()->SendBuf(hdr.socket_handle, buff, sizeof(f8::PackHead) + head->packlen);
}
free(buff);
}
void DownStream::OnClose()
{
if (!GetUpStream().expired()) {
ss::SS_WSP_SocketDisconnect msg;
GetUpStream().lock()->SendMsg(socket_handle_, msg);
}
if (!long_session_wp_.expired()) {
LongSessionMgr::Instance()->DelSession(socket_handle_);
}
}
void DownStream::ProcCMMsg(f8::MsgHdr& hdr, int tag)
{
if (hdr.msgid == ss::_SS_CMPing && IsLongSession() && tag == ST_Tcp) {
ss::SS_SMPing msg;
GCListener::Instance()->SendMsgEx(socket_handle_, ss::_SS_CMPing, msg);
if (!long_session_wp_.expired()) {
long_session_wp_.lock()->UpdatePing();
}
return;
}
if (!GetUpStream().expired()) {
GetUpStream().lock()->ForwardClientMsg(hdr);
}
}

View File

@ -0,0 +1,25 @@
#pragma once
class UpStream;
class LongSession;
class DownStream
{
public:
void Init(int socket_handle, std::weak_ptr<UpStream> up);
int GetSocketHandle() const { return socket_handle_; }
std::weak_ptr<UpStream> GetUpStream() const { return up_; }
void ReBindUpStream(std::weak_ptr<UpStream> up);
bool IsLongSession() { return is_long_session_; }
void ProcCMMsg(f8::MsgHdr& hdr, int tag);
void ForwardUpStreamMsg(f8::MsgHdr& hdr);
void OnClose();
private:
int socket_handle_ = a8::INVALID_SOCKET_HANDLE;
std::weak_ptr<UpStream> up_;
bool is_long_session_ = false;
std::weak_ptr<LongSession> long_session_wp_;
};

View File

@ -0,0 +1,159 @@
#include "precompile.h"
#include <f8/udplog.h>
#include <f8/msgqueue.h>
#include "downstreammgr.h"
#include "ss_proto.pb.h"
#include "downstream.h"
#include "upstream.h"
#include "upstreammgr.h"
#include "GCListener.h"
#include "app.h"
#include "mastermgr.h"
struct PendingAccount
{
int socket_handle = 0;
std::string account_id;
long long add_tick = 0;
f8::TimerWp timer_wp;
};
void DownStreamMgr::Init()
{
f8::MsgQueue::Instance()->RegisterCallBack
(
IM_ClientSocketDisconnect,
[this] (const a8::Args& args)
{
int socket_handle = args.Get<int>(0);
OnClientDisconnect(socket_handle);
});
}
void DownStreamMgr::UnInit()
{
socket_hash_.clear();
pending_account_hash_.clear();
}
void DownStreamMgr::OnClientDisconnect(int socket_handle)
{
auto down_wp = GetDownStream(socket_handle);
if (auto down = down_wp.lock(); !down_wp.expired()) {
down->OnClose();
socket_hash_.erase(socket_handle);
}
RemovePendingAccount(socket_handle);
MasterMgr::Instance()->RemoveRequest(socket_handle);
}
void DownStreamMgr::OnUpStreamDisconnect(int instance_id)
{
std::list<std::shared_ptr<DownStream>> delete_client;
for (auto& pair : socket_hash_) {
if (!pair.second->GetUpStream().expired() &&
pair.second->GetUpStream().lock()->instance_id == instance_id) {
delete_client.push_back(pair.second);
}
}
for (auto& client : delete_client) {
RemovePendingAccount(client->GetSocketHandle());
GCListener::Instance()->ForceCloseClient(client->GetSocketHandle());
socket_hash_.erase(client->GetSocketHandle());
}
}
void DownStreamMgr::OnUpStreamConnect(int instance_id)
{
}
std::weak_ptr<DownStream> DownStreamMgr::GetDownStream(int sockhandle)
{
auto itr = socket_hash_.find(sockhandle);
return itr != socket_hash_.end() ? itr->second : nullptr;
}
void DownStreamMgr::BindUpStream(int socket_handle, int instance_id)
{
std::weak_ptr<UpStream> up_wp = UpStreamMgr::Instance()->GetUpStreamById(instance_id);
if (!up_wp.expired()) {
auto down_wp = GetDownStream(socket_handle);
if (auto down = down_wp.lock(); !down_wp.expired()) {
down->ReBindUpStream(up_wp);
} else {
down = std::make_shared<DownStream>();
down->Init(socket_handle, up_wp);
socket_hash_[down->GetSocketHandle()] = down;
f8::UdpLog::Instance()->Info("BindUpStream socket_handle:%d",
{
socket_handle
});
{
if (auto pending_account = GetPendingAccount(socket_handle)) {
long long cur_tick = a8::XGetTickCount();
if (cur_tick - pending_account->add_tick > App::Instance()->GetPerf().max_join_time) {
App::Instance()->GetPerf().max_join_time = cur_tick - pending_account->add_tick;
}
f8::UdpLog::Instance()->Info("BindUpStream account_id:%s",
{
pending_account->account_id
});
RemovePendingAccount(socket_handle);
}
}
}
}
}
void DownStreamMgr::AddPendingAccount(const std::string& account_id, int socket_handle, long long req_tick)
{
f8::UdpLog::Instance()->Info("AddPendingAccount %s %d", {account_id, socket_handle});
if (!GetPendingAccount(socket_handle)){
auto timer_wp = f8::Timer::Instance()->SetTimeoutWpEx
(
1000 * 10,
[this, socket_handle] (int event, const a8::Args* args)
{
if (a8::TIMER_EXEC_EVENT == event) {
pending_account_hash_.erase(socket_handle);
App::Instance()->GetPerf().max_join_time =
std::max((long long)1000 * 10, App::Instance()->GetPerf().max_join_time);
}
},
&timer_attacher_
);
auto p = std::make_shared<PendingAccount>();
p->socket_handle = socket_handle;
p->account_id = account_id;
p->add_tick = req_tick;
p->timer_wp = timer_wp;
pending_account_hash_[socket_handle] = p;
}
}
std::shared_ptr<PendingAccount> DownStreamMgr::GetPendingAccount(int socket_handle)
{
auto itr = pending_account_hash_.find(socket_handle);
return itr != pending_account_hash_.end() ? itr->second : nullptr;
}
void DownStreamMgr::RemovePendingAccount(int socket_handle)
{
auto itr = pending_account_hash_.find(socket_handle);
if (itr != pending_account_hash_.end()) {
f8::UdpLog::Instance()->Info("RemovePendingAccount %d", {socket_handle});
if (!itr->second->timer_wp.expired()) {
f8::Timer::Instance()->Delete(itr->second->timer_wp);
}
pending_account_hash_.erase(itr);
}
}
int DownStreamMgr::GetDownStreamCount()
{
return socket_hash_.size();
}

View File

@ -0,0 +1,35 @@
#pragma once
#include <f8/timer.h>
class DownStream;
struct PendingAccount;
class DownStreamMgr : public a8::Singleton<DownStreamMgr>
{
private:
DownStreamMgr() {};
friend class a8::Singleton<DownStreamMgr>;
public:
void Init();
void UnInit();
void OnUpStreamDisconnect(int instance_id);
void OnUpStreamConnect(int instance_id);
std::weak_ptr<DownStream> GetDownStream(int sockhande);
void BindUpStream(int socket_handle, int instance_id);
void AddPendingAccount(const std::string& account_id, int socket_handle, long long req_tick);
int GetDownStreamCount();
private:
void OnClientDisconnect(int socket_handle);
std::shared_ptr<PendingAccount> GetPendingAccount(int socket_handle);
void RemovePendingAccount(int socket_handle);
private:
f8::Attacher timer_attacher_;
std::map<int, std::shared_ptr<DownStream>> socket_hash_;
std::map<int, std::shared_ptr<PendingAccount>> pending_account_hash_;
};

View File

@ -1,3 +0,0 @@
#include "precompile.h"
#include "gameclient.h"

View File

@ -1,10 +0,0 @@
#pragma once
class TargetConn;
class GameClient
{
public:
int socket_handle = a8::INVALID_SOCKET_HANDLE;
TargetConn* conn = nullptr;
};

View File

@ -1,134 +0,0 @@
#include "precompile.h"
#include "gameclientmgr.h"
#include "ss_proto.pb.h"
#include "gameclient.h"
#include "target_conn.h"
#include "target_conn_mgr.h"
#include "GCListener.h"
#include "app.h"
void GameClientMgr::Init()
{
}
void GameClientMgr::UnInit()
{
for (auto& pair : socket_hash_) {
delete pair.second;
}
socket_hash_.clear();
pending_account_hash_.clear();
}
void GameClientMgr::OnClientDisconnect(a8::XParams& param)
{
GameClient* client = GetGameClientBySocket(param.sender);
if (client) {
if (client->conn) {
ss::SS_WSP_SocketDisconnect msg;
client->conn->SendMsg(param.sender, msg);
}
socket_hash_.erase(param.sender);
delete client;
}
RemovePendingAccount(param.sender);
}
void GameClientMgr::OnTargetServerDisconnect(a8::XParams& param)
{
std::list<GameClient*> delete_client;
for (auto& pair : socket_hash_) {
if (pair.second->conn && pair.second->conn->instance_id == param.sender.GetInt()) {
delete_client.push_back(pair.second);
}
}
for (auto& client : delete_client) {
RemovePendingAccount(client->socket_handle);
GCListener::Instance()->ForceCloseClient(client->socket_handle);
socket_hash_.erase(client->socket_handle);
delete client;
}
}
void GameClientMgr::OnTargetServerConnect(a8::XParams& param)
{
}
GameClient* GameClientMgr::GetGameClientBySocket(int sockhandle)
{
auto itr = socket_hash_.find(sockhandle);
return itr != socket_hash_.end() ? itr->second : nullptr;
}
void GameClientMgr::BindTargetConn(int socket_handle, int conn_instance_id)
{
TargetConn* conn = TargetConnMgr::Instance()->GetConnById(conn_instance_id);
if (conn) {
GameClient* client = GetGameClientBySocket(socket_handle);
if (client) {
client->conn = conn;
} else {
client = new GameClient();
client->socket_handle = socket_handle;
client->conn = conn;
socket_hash_[client->socket_handle] = client;
a8::UdpLog::Instance()->Info("BindTargetConn socket_handle:%d", {socket_handle});
{
auto itr = pending_account_hash_.find(socket_handle);
if (itr != pending_account_hash_.end()) {
std::string account_id = std::get<0>(itr->second);
long long req_tick = std::get<1>(itr->second);
long long cur_tick = a8::XGetTickCount();
if (cur_tick - req_tick > App::Instance()->perf.max_join_time) {
App::Instance()->perf.max_join_time = cur_tick - req_tick;
}
if (account_id == azw_account_id) {
a8::UdpLog::Instance()->Info("%s join time:%d",
{
account_id,
cur_tick - req_tick
});
}
a8::UdpLog::Instance()->Info("BindTargetConn account_id:%s", {account_id});
RemovePendingAccount(socket_handle);
}
}
}
}
}
void GameClientMgr::AddPendingAccount(const std::string& account_id, int socket_handle, long long req_tick)
{
a8::UdpLog::Instance()->Info("AddPendingAccount %s %d", {account_id, socket_handle});
auto itr = pending_account_hash_.find(socket_handle);
if (itr == pending_account_hash_.end()){
timer_list* timer = a8::Timer::Instance()->AddDeadLineTimerAndAttach(1000 * 10,
a8::XParams()
.SetSender(socket_handle),
[] (const a8::XParams& param)
{
GameClientMgr::Instance()->pending_account_hash_.erase(param.sender);
App::Instance()->perf.max_join_time = std::max((long long)1000 * 10, App::Instance()->perf.max_join_time);
},
&timer_attacher_.timer_list_
);
pending_account_hash_[socket_handle] = std::make_tuple(
account_id,
req_tick,
timer
);
}
}
void GameClientMgr::RemovePendingAccount(int socket_handle)
{
a8::UdpLog::Instance()->Info("RemovePendingAccount %d", {socket_handle});
auto itr = pending_account_hash_.find(socket_handle);
if (itr != pending_account_hash_.end()) {
a8::Timer::Instance()->DeleteTimer(std::get<2>(itr->second));
pending_account_hash_.erase(itr);
}
}

View File

@ -1,32 +0,0 @@
#pragma once
#include <a8/timer.h>
class GameClient;
class GameClientMgr : public a8::Singleton<GameClientMgr>
{
private:
GameClientMgr() {};
friend class a8::Singleton<GameClientMgr>;
public:
void Init();
void UnInit();
void OnClientDisconnect(a8::XParams& param);
void OnTargetServerDisconnect(a8::XParams& param);
void OnTargetServerConnect(a8::XParams& param);
GameClient* GetGameClientBySocket(int sockhande);
void BindTargetConn(int socket_handle, int conn_instance_id);
void AddPendingAccount(const std::string& account_id, int socket_handle, long long req_tick);
private:
void RemovePendingAccount(int socket_handle);
private:
a8::TimerAttacher timer_attacher_;
std::map<int, GameClient*> socket_hash_;
std::map<int, std::tuple<std::string, long long, timer_list*>> pending_account_hash_;
};

View File

@ -1,16 +1,19 @@
#include "precompile.h"
#include <a8/mutable_xobject.h>
#include <f8/msgqueue.h>
#include <f8/jsonhttprequest.h>
#include "handlermgr.h"
#include "GCListener.h"
#include "mastersvrmgr.h"
#include "mastermgr.h"
#include "app.h"
#include "jsondatamgr.h"
#include "ss_proto.pb.h"
static void _GMOpsSelfChecking(f8::JsonHttpRequest* request)
static void _GMOpsSelfChecking(std::shared_ptr<f8::JsonHttpRequest> request)
{
request->resp_xobj->SetVal("errcode", 0);
request->resp_xobj->SetVal("errmsg", "");
@ -18,11 +21,28 @@ static void _GMOpsSelfChecking(f8::JsonHttpRequest* request)
request->resp_xobj->SetVal("max_rundelay", 10);
}
static void _GMOpsGetNodeId(f8::JsonHttpRequest* request)
static void _GMOpsGetNodeId(std::shared_ptr<f8::JsonHttpRequest> request)
{
request->resp_xobj->SetVal("errcode", 0);
request->resp_xobj->SetVal("errmsg", "");
request->resp_xobj->SetVal("node_id", App::Instance()->node_id);
request->resp_xobj->SetVal("node_id", App::Instance()->GetNodeId());
}
static void _GMOpsSetKcpSwitch(std::shared_ptr<f8::JsonHttpRequest> request)
{
request->resp_xobj->SetVal("errcode", 0);
request->resp_xobj->SetVal("errmsg", "");
if (request->params->HasKey("open")) {
JsonDataMgr::Instance()->SetKcpSwitch(request->params->At("open")->AsXValue().GetInt());
}
request->resp_xobj->SetVal("is_open", JsonDataMgr::Instance()->GetKcpConf().open);
}
static void _GMOpsGetKcpSwitch(std::shared_ptr<f8::JsonHttpRequest> request)
{
request->resp_xobj->SetVal("errcode", 0);
request->resp_xobj->SetVal("errmsg", "");
request->resp_xobj->SetVal("is_open", JsonDataMgr::Instance()->GetKcpConf().open);
}
void HandlerMgr::Init()
@ -30,6 +50,19 @@ void HandlerMgr::Init()
RegisterNetMsgHandlers();
RegisterGMMsgHandler("Ops$selfChecking", _GMOpsSelfChecking);
RegisterGMMsgHandler("Ops$getNodeId", _GMOpsGetNodeId);
RegisterGMMsgHandler("Ops$setKcpSwitch", _GMOpsSetKcpSwitch);
RegisterGMMsgHandler("Ops$getKcpSwitch", _GMOpsGetKcpSwitch);
f8::MsgQueue::Instance()->RegisterCallBack
(
IM_ExecGM,
[this] (const a8::Args& args)
{
int socket_handle = args.Get<int>(0);
std::string url = args.Get<std::string>(1);
std::string query_str = args.Get<std::string>(2);
unsigned long saddr = args.Get<unsigned long>(3);
ProcGMMsg(saddr, socket_handle, url, query_str);
});
}
void HandlerMgr::UnInit()
@ -38,7 +71,7 @@ void HandlerMgr::UnInit()
void HandlerMgr::RegisterNetMsgHandlers()
{
RegisterNetMsgHandler(&msmsghandler, &MasterSvrMgr::_SS_MS_ResponseTargetServer);
RegisterNetMsgHandler(&msmsghandler, &MasterMgr::_SS_MS_ResponseTargetServer);
}
void HandlerMgr::ProcGMMsg(unsigned long saddr, int sockhandle,
@ -55,19 +88,17 @@ void HandlerMgr::ProcGMMsg(unsigned long saddr, int sockhandle,
std::string msgname = a8::Get(request, "c").GetString() + "$" + a8::Get(request, "a").GetString();
auto itr = gmhandlers_.find(msgname);
if (itr != gmhandlers_.end()) {
f8::JsonHttpRequest* request = new f8::JsonHttpRequest;
auto request = std::make_shared<f8::JsonHttpRequest>();
request->saddr = saddr;
request->socket_handle = sockhandle;
request->query_str = querystr;
request->request.ReadFromUrlQueryString(querystr);
request->params->ReadFromUrlQueryString(querystr);
itr->second(request);
if (!request->pending){
std::string response;
request->resp_xobj->ToJsonStr(response);
GCListener::Instance()->SendText(sockhandle, a8::HttpResponse(response));
delete request;
}
} else {
GCListener::Instance()->SendText(sockhandle, a8::HttpResponse("{}"));
@ -75,7 +106,7 @@ void HandlerMgr::ProcGMMsg(unsigned long saddr, int sockhandle,
}
void HandlerMgr::RegisterGMMsgHandler(const std::string& msgname,
void (*handler)(f8::JsonHttpRequest*))
void (*handler)(std::shared_ptr<f8::JsonHttpRequest>))
{
gmhandlers_[msgname] = handler;
}

View File

@ -2,7 +2,7 @@
#include <a8/basehttpsession.h>
#include "framework/cpp/netmsghandler.h"
#include <f8/netmsghandler.h>
namespace a8
{
@ -30,7 +30,7 @@ class HandlerMgr : public a8::Singleton<HandlerMgr>
private:
void RegisterNetMsgHandlers();
void RegisterGMMsgHandler(const std::string& msgname,
void (*)(f8::JsonHttpRequest*));
void (*)(std::shared_ptr<f8::JsonHttpRequest>));
std::map<std::string, void (*)(f8::JsonHttpRequest*)> gmhandlers_;
std::map<std::string, void (*)(std::shared_ptr<f8::JsonHttpRequest>)> gmhandlers_;
};

1
server/wsproxy/ikcp.c Symbolic link
View File

@ -0,0 +1 @@
../../third_party/kcp/ikcp.c

1
server/wsproxy/ikcp.h Symbolic link
View File

@ -0,0 +1 @@
../../third_party/kcp/ikcp.h

View File

@ -2,129 +2,114 @@
#include <mutex>
#include <f8/utils.h>
#include <f8/udplog.h>
#include "jsondatamgr.h"
#include "app.h"
void JsonDataMgr::Init()
{
#if MASTER_MODE
node_host_mutex_ = new std::mutex();
#endif
if (!f8::IsOnlineEnv()) {
if (f8::IsTestEnv()) {
work_path_ = a8::Format("/root/pub/%d/%d/conf_test/game%d/wsproxy.test",
{
GAME_ID,
App::Instance()->instance_id,
GAME_ID
});
} else {
work_path_ = a8::Format("/root/pub/%d/%d/conf_test/game%d/wsproxy.dev",
{
GAME_ID,
App::Instance()->instance_id,
GAME_ID
});
}
work_path_ = a8::Format
("../../../conf_test/game%d/%s",
{
GAME_ID,
f8::IsTestEnv() ? "wsproxy.test" : "wsproxy.dev"
});
}
std::string wsproxyserver_cluster_json_file;
#if MASTER_MODE
std::string masterserver_cluster_json_file;
std::string routing_tables_json_file;
wsproxyserver_cluster_json_file = a8::Format("%s/node%d/game%d.wsproxy.cluster.json",
{
work_path_,
App::Instance()->node_id,
GAME_ID
});
masterserver_cluster_json_file = a8::Format("%s/node%d/game%d.masterserver.cluster.json",
{
work_path_,
App::Instance()->node_id,
GAME_ID
});
routing_tables_json_file = a8::Format("%s/routing_tables.json",
{
work_path_
});
#else
std::string targetserver_cluster_json_file;
wsproxyserver_cluster_json_file = a8::Format("%s/game%d.wsproxy.cluster.json",
{
work_path_,
GAME_ID
});
targetserver_cluster_json_file = a8::Format("%s/game%d.gameserver.cluster.json",
{
work_path_,
GAME_ID
});
#endif
std::string wsproxy_cluster_json_file;
std::string master_cluster_json_file;
std::string kcp_conf_json_file;
wsproxy_cluster_json_file = a8::Format
("%s/node%d/game%d.wsproxy.cluster.json",
{
work_path_,
App::Instance()->GetNodeId(),
GAME_ID
});
master_cluster_json_file = a8::Format
("%s/node%d/game%d.masterserver.cluster.json",
{
work_path_,
App::Instance()->GetNodeId(),
GAME_ID
});
kcp_conf_json_file = a8::Format
("%s/kcp_conf.json",
{
work_path_,
});
wsproxy_cluster_json_.ReadFromFile(wsproxy_cluster_json_file);
master_cluster_json_.ReadFromFile(master_cluster_json_file);
kcp_conf_json_.ReadFromFile(kcp_conf_json_file);
udp_host_ = GetConf()->At("listen_udp_host")->AsXValue().GetString();
udp_port_ = GetConf()->At("listen_udp_port")->AsXValue();
{
kcp_conf_.open = kcp_conf_json_.At("open")->AsXValue();
kcp_conf_.sndwnd = kcp_conf_json_.At("sndwnd")->AsXValue();
kcp_conf_.rcvwnd = kcp_conf_json_.At("rcvwnd")->AsXValue();
kcp_conf_.nodelay = kcp_conf_json_.At("nodelay")->AsXValue();
kcp_conf_.interval = kcp_conf_json_.At("interval")->AsXValue();
kcp_conf_.resend = kcp_conf_json_.At("resend")->AsXValue();
kcp_conf_.nc = kcp_conf_json_.At("nc")->AsXValue();
kcp_conf_.rx_minrto = kcp_conf_json_.At("rx_minrto")->AsXValue();
kcp_conf_.fastresend = kcp_conf_json_.At("fastresend")->AsXValue();
f8::UdpLog::Instance()->Info
(" kcp_conf open:%d sndwnd:%d rcvwnd:%d "
"nodelay:%d interval:%d resend:%d nc:%d "
"rx_minrto:%d fastresend:%d",
{
kcp_conf_.open,
kcp_conf_.sndwnd,
kcp_conf_.rcvwnd,
kcp_conf_.nodelay,
kcp_conf_.interval,
kcp_conf_.resend,
kcp_conf_.nc,
kcp_conf_.rx_minrto,
kcp_conf_.fastresend
});
wsproxyserver_cluster_json_.ReadFromFile(wsproxyserver_cluster_json_file);
#if MASTER_MODE
masterserver_cluster_json_.ReadFromFile(masterserver_cluster_json_file);
routing_tables_json_.ReadFromFile(routing_tables_json_file);
node_host_mutex_->lock();
for (int i = 0; i < routing_tables_json_.Size(); ++i) {
auto node_conf = routing_tables_json_.At(i);
int node_id = node_conf->At("node_id")->AsXValue();
std::string host = node_conf->At("host")->AsXValue();
if (node_host_hash_.find(node_id) != node_host_hash_.end()) {
abort();
}
node_host_hash_[node_id] = host;
}
node_host_mutex_->unlock();
#else
targetserver_cluster_json_.ReadFromFile(targetserver_cluster_json_file);
#endif
}
void JsonDataMgr::UnInit()
{
#if MASTER_MODE
delete node_host_mutex_;
node_host_mutex_ = nullptr;
#endif
}
std::shared_ptr<a8::XObject> JsonDataMgr::GetConf()
{
if (App::Instance()->instance_id < 1 || App::Instance()->instance_id > wsproxyserver_cluster_json_.Size()) {
abort();
for (int i = 0; i < wsproxy_cluster_json_.Size(); ++i) {
std::shared_ptr<a8::XObject> conf = wsproxy_cluster_json_.At(i);
if (conf->At("instance_id")->AsXValue().GetInt() == App::Instance()->GetInstanceId()) {
return conf;
}
}
return wsproxyserver_cluster_json_[App::Instance()->instance_id - 1];
A8_ABORT();
}
std::shared_ptr<a8::XObject> JsonDataMgr::GetMasterServerClusterConf()
void JsonDataMgr::TraverseMaster(std::function<void (int, std::string, int)> cb)
{
return std::make_shared<a8::XObject>(masterserver_cluster_json_);
}
#if MASTER_MODE
bool JsonDataMgr::GetNodeHost(int node_id, std::string& host)
{
bool found = false;
node_host_mutex_->lock();
auto itr = node_host_hash_.find(node_id);
if (itr != node_host_hash_.end()) {
//!!!因为std::string基于引用计数多线程下直接复制的话会有问题所以要用这种方式赋值
host = itr->second.c_str();
found = true;
for (int i = 0; i < master_cluster_json_.Size(); ++i) {
auto master_svr_conf = master_cluster_json_.At(i);
int instance_id = master_svr_conf->At("instance_id")->AsXValue();
std::string remote_ip = master_svr_conf->At("ip")->AsXValue();
int remote_port = master_svr_conf->At("port")->AsXValue();
cb(instance_id, remote_ip, remote_port);
}
node_host_mutex_->unlock();
return found;
}
#else
std::shared_ptr<a8::XObject> JsonDataMgr::GetTargetServerClusterConf()
void JsonDataMgr::SetKcpSwitch(int is_open)
{
return std::make_shared<a8::XObject>(targetserver_cluster_json_);
kcp_conf_.open = is_open ? 1 : 0;
}
#endif

View File

@ -1,5 +1,23 @@
#pragma once
#include <a8/singleton.h>
struct KcpConf
{
int open = 0;
int sndwnd = 0;
int rcvwnd = 0;
int nodelay = 0;
int interval = 0;
int resend = 0;
int nc = 0;
int rx_minrto = 0;
int fastresend = 0;
};
class JsonDataMgr : public a8::Singleton<JsonDataMgr>
{
private:
@ -10,23 +28,19 @@ class JsonDataMgr : public a8::Singleton<JsonDataMgr>
void Init();
void UnInit();
std::string GetUdpHost() { return udp_host_; }
int GetUdpPort() { return udp_port_; }
std::shared_ptr<a8::XObject> GetConf();
std::shared_ptr<a8::XObject> GetMasterServerClusterConf();
#if MASTER_MODE
bool GetNodeHost(int node_id, std::string& host);
#else
std::shared_ptr<a8::XObject> GetTargetServerClusterConf();
#endif
void TraverseMaster(std::function<void (int, std::string, int)> cb);
const KcpConf& GetKcpConf() { return kcp_conf_; }
void SetKcpSwitch(int is_open);
private:
std::string work_path_ = "../config";
a8::XObject wsproxyserver_cluster_json_;
a8::XObject masterserver_cluster_json_;
#if MASTER_MODE
std::mutex* node_host_mutex_ = nullptr;
a8::XObject routing_tables_json_;
std::map<int, std::string> node_host_hash_;
#else
a8::XObject targetserver_cluster_json_;
#endif
a8::XObject wsproxy_cluster_json_;
a8::XObject master_cluster_json_;
a8::XObject kcp_conf_json_;
std::string udp_host_;
int udp_port_ = 0;
KcpConf kcp_conf_ = {};
};

View File

@ -0,0 +1,185 @@
#include "precompile.h"
#include <memory.h>
#include <string.h>
#include <f8/netmsghandler.h>
#include <f8/udplog.h>
#include "kcpsession.h"
#include "longsessionmgr.h"
#include "jsondatamgr.h"
#include "app.h"
static const int DEFAULT_MAX_RECV_BUFFERSIZE = 1024 * 64;
static int UdpOutput(const char *buf, int len, ikcpcb *kcp, void *user)
{
KcpSession* session = (KcpSession*)user;
a8::UdpPacket pkt;
pkt.buf = buf;
pkt.buf_len = len;
pkt.remote_addr = session->GetAddr();
LongSessionMgr::Instance()->GetUdpListener()->SendUdpPacket(&pkt);
return 0;
}
KcpSession::KcpSession()
{
}
KcpSession::~KcpSession()
{
}
void KcpSession::Init(int socket_handle, int secret_key_place)
{
socket_handle_ = socket_handle;
secret_key_ = App::Instance()->NewUuid();
kcp_ = ikcp_create(socket_handle_, (void*)this);
const KcpConf& kcp_conf = JsonDataMgr::Instance()->GetKcpConf();
ikcp_wndsize(kcp_, kcp_conf.sndwnd, kcp_conf.rcvwnd);
ikcp_nodelay(kcp_, kcp_conf.nodelay, kcp_conf.interval, kcp_conf.resend, kcp_conf.nc);
kcp_->rx_minrto = kcp_conf.rx_minrto;
kcp_->fastresend = kcp_conf.fastresend;
secret_key_place_ = secret_key_place;
if (secret_key_place_ > 0) {
secret_key_place_ = 1;
} else if (secret_key_place_ < 0) {
secret_key_place_ = 0;
}
kcp_->output = UdpOutput;
init_tick_ = a8::XGetTickCount();
}
void KcpSession::UnInit()
{
if (kcp_) {
ikcp_release(kcp_);
kcp_ = nullptr;
}
}
void KcpSession::Update(long long tick)
{
ikcp_update(kcp_, tick - init_tick_);
UpdateInput();
}
void KcpSession::SendClientMsg(char* buf, int buf_len)
{
ikcp_send(kcp_, buf, buf_len);
}
void KcpSession::OnRecvPacket(a8::UdpPacket* pkt)
{
const int IKCP_OVERHEAD = 24;
remote_addr_ = pkt->remote_addr;
if (GetSecretKeyPlace()) {
char* buf = (char*)malloc(pkt->buf_len - GetSecretKeyLen());
int buflen = pkt->buf_len - GetSecretKeyLen();
memmove(buf, pkt->buf, IKCP_OVERHEAD);
if (pkt->buf_len > IKCP_OVERHEAD + GetSecretKeyLen()) {
memmove(buf + IKCP_OVERHEAD, pkt->buf + IKCP_OVERHEAD + GetSecretKeyLen(), buflen - IKCP_OVERHEAD);
}
ikcp_input(kcp_, buf, buflen);
free(buf);
} else {
ikcp_input(kcp_, pkt->buf, pkt->buf_len);
}
}
void KcpSession::UpdateInput()
{
char buf[DEFAULT_MAX_RECV_BUFFERSIZE];
int buflen = ikcp_recv(kcp_, buf, DEFAULT_MAX_RECV_BUFFERSIZE - 10);
if (buflen <= 0) {
return;
}
OnSocketRead(buf, buflen);
}
void KcpSession::DecodeUserPacket(char* buf, int& offset, unsigned int buflen)
{
if (GetSecretKeyPlace()) {
DecodeUserPacketNew(buf, offset, buflen);
} else {
DecodeUserPacketOld(buf, offset, buflen);
}
}
int KcpSession::GetSecretKeyPlace()
{
return secret_key_place_;
}
void KcpSession::DecodeUserPacketOld(char* buf, int& offset, unsigned int buflen)
{
bool warning = false;
while (buflen - offset >= sizeof(f8::PackHead) + GetSecretKeyLen()) {
long long secret_key = KcpSession::ReadSecretKey(&buf[offset], buflen);
if (secret_key != secret_key_) {
warning = true;
offset++;
continue;
}
f8::PackHead* p = (f8::PackHead*)&buf[offset + GetSecretKeyLen()];
if (p->magic_code == f8::MAGIC_CODE) {
if (buflen - offset < sizeof(f8::PackHead) + p->packlen + GetSecretKeyLen()) {
break;
}
App::Instance()->AddSocketMsg(SF_Client,
socket_handle_,
0,
//saddr,
p->msgid,
p->seqid,
&buf[offset + sizeof(f8::PackHead) + GetSecretKeyLen()],
p->packlen,
ST_Udp);
offset += sizeof(f8::PackHead) + p->packlen + GetSecretKeyLen();
} else {
warning = true;
offset++;
continue;
}
}
if (warning) {
f8::UdpLog::Instance()->Warning("收到kcp client非法数据包1", {});
}
}
void KcpSession::DecodeUserPacketNew(char* buf, int& offset, unsigned int buflen)
{
bool warning = false;
while (buflen - offset >= sizeof(f8::PackHead)) {
f8::PackHead* p = (f8::PackHead*)&buf[offset];
if (p->magic_code == f8::MAGIC_CODE) {
if (buflen - offset < sizeof(f8::PackHead) + p->packlen) {
break;
}
App::Instance()->AddSocketMsg(SF_Client,
socket_handle_,
0,
//saddr,
p->msgid,
p->seqid,
&buf[offset + sizeof(f8::PackHead)],
p->packlen,
ST_Udp);
offset += sizeof(f8::PackHead) + p->packlen;
} else {
warning = true;
offset++;
continue;
}
}
if (warning) {
f8::UdpLog::Instance()->Warning("收到kcp client非法数据包2", {});
}
}

View File

@ -0,0 +1,49 @@
#pragma once
#include <a8/udpsession.h>
#include <a8/udplistener.h>
#include "ikcp.h"
class KcpSession : public a8::UdpSession
{
public:
KcpSession();
~KcpSession();
void Init(int socket_handle, int secret_key_place);
void UnInit();
void Update(long long tick);
const sockaddr_in& GetAddr() const { return remote_addr_; }
int GetSocketHandle() { return socket_handle_; }
long long GetSecretKey() { return secret_key_; }
void* GetSecretKeyDataPtr() { return &secret_key_; }
int GetSecretKeyPlace();
void SendClientMsg(char* buf, int buf_len);
virtual void OnRecvPacket(a8::UdpPacket* pkt) override;
static int GetSecretKeyLen() { return sizeof(long long); }
static long long ReadSecretKey(const char* buf, int buf_len)
{
return buf_len < GetSecretKeyLen() ? 0 : *((long long*)buf);
}
protected:
virtual void DecodeUserPacket(char* buf, int& offset, unsigned int buflen) override;
void DecodeUserPacketOld(char* buf, int& offset, unsigned int buflen);
void DecodeUserPacketNew(char* buf, int& offset, unsigned int buflen);
private:
void UpdateInput();
private:
int secret_key_place_ = 0;
int socket_handle_ = 0;
long long secret_key_ = 0;
ikcpcb* kcp_ = nullptr;
long long init_tick_ = 0;
sockaddr_in remote_addr_ = {};
};

View File

@ -0,0 +1,35 @@
#include "precompile.h"
#include <f8/netmsghandler.h>
#include "longsession.h"
#include "kcpsession.h"
#include "ss_msgid.pb.h"
#include "ss_proto.pb.h"
void LongSession::Init(f8::MsgHdr& hdr, const ss::SS_CMKcpHandshake& msg)
{
kcp_session_ = std::make_shared<KcpSession>();
kcp_session_->Init(hdr.socket_handle, msg.secret_key_place());
}
void LongSession::UnInit()
{
kcp_session_->UnInit();
}
void LongSession::Update(long long tick)
{
GetKcpSession()->Update(tick);
}
void LongSession::UpdatePing()
{
last_ping_tick_ = a8::XGetTickCount();
}
int LongSession::GetSecretKeyPlace()
{
return kcp_session_->GetSecretKeyPlace();
}

View File

@ -0,0 +1,25 @@
#pragma once
namespace ss
{
class SS_CMKcpHandshake;
}
class KcpSession;
class LongSession
{
public:
void Init(f8::MsgHdr& hdr, const ss::SS_CMKcpHandshake& msg);
void UnInit();
void Update(long long tick);
std::shared_ptr<KcpSession> GetKcpSession() { return kcp_session_; }
void UpdatePing();
int GetSecretKeyPlace();
private:
long long last_ping_tick_ = 0;
std::shared_ptr<KcpSession> kcp_session_;
};

View File

@ -0,0 +1,182 @@
#include "precompile.h"
#include <a8/udplistener.h>
#include <f8/netmsghandler.h>
#include <f8/udplog.h>
#include "longsessionmgr.h"
#include "app.h"
#include "jsondatamgr.h"
#include "longsession.h"
#include "kcpsession.h"
#include "GCListener.h"
#include "downstreammgr.h"
#include "ss_msgid.pb.h"
#include "ss_proto.pb.h"
static void GSUdpListeneron_error(int errorid)
{
f8::UdpLog::Instance()->Debug("GCUdpListeneron_error %d", {errorid});
}
static void GSUdpListeneron_recv_packet(a8::UdpPacket* pkt)
{
App::Instance()->AddUdpMsg(pkt);
}
void LongSessionMgr::Init()
{
udp_listener_ = std::make_shared<a8::UdpListener>();
udp_listener_->on_error = GSUdpListeneron_error;
udp_listener_->on_recv_packet = GSUdpListeneron_recv_packet;
udp_listener_->bind_address = "0.0.0.0";
udp_listener_->bind_port = JsonDataMgr::Instance()->GetUdpPort();
udp_listener_->Open();
}
void LongSessionMgr::UnInit()
{
for (auto& pair : socket_handle_hash_) {
pair.second->UnInit();
}
socket_handle_hash_.clear();
}
void LongSessionMgr::Update()
{
long long tick = a8::XGetTickCount();
for (auto& pair : socket_handle_hash_) {
pair.second->Update(tick);
}
}
void LongSessionMgr::_SS_CMKcpHandshake(f8::MsgHdr& hdr, const ss::SS_CMKcpHandshake& msg)
{
ss::SS_SMKcpHandshake respmsg;
respmsg.set_errcode(0);
if (!JsonDataMgr::Instance()->GetKcpConf().open) {
respmsg.set_errcode(1);
respmsg.set_errmsg("not support kcp");
GCListener::Instance()->SendMsgEx(hdr.socket_handle, ss::_SS_CMKcpHandshake, respmsg);
return;
}
if (GetSession(hdr.socket_handle)) {
#ifdef DEBUG
abort();
#endif
return;
}
auto session = std::make_shared<LongSession>();
session->Init(hdr, msg);
socket_handle_hash_[session->GetKcpSession()->GetSocketHandle()] = session;
respmsg.set_conv(session->GetKcpSession()->GetSocketHandle());
respmsg.set_secret_key(session->GetKcpSession()->GetSecretKeyDataPtr(), KcpSession::GetSecretKeyLen());
respmsg.set_remote_host(JsonDataMgr::Instance()->GetUdpHost());
respmsg.set_remote_port(JsonDataMgr::Instance()->GetUdpPort());
GCListener::Instance()->SendMsgEx(hdr.socket_handle, ss::_SS_CMKcpHandshake, respmsg);
{
int socket_handle = hdr.socket_handle;
f8::Timer::Instance()->SetTimeout
(
1000 * 30,
[this, socket_handle] (int event, const a8::Args* args)
{
if (a8::TIMER_EXEC_EVENT == event) {
if (DownStreamMgr::Instance()->GetDownStream(socket_handle).expired()) {
GCListener::Instance()->ForceCloseClient(socket_handle);
}
}
}
);
}
}
std::shared_ptr<LongSession> LongSessionMgr::GetSession(int socket_handle)
{
auto itr = socket_handle_hash_.find(socket_handle);
return itr != socket_handle_hash_.end() ? itr->second : nullptr;
}
void LongSessionMgr::ProcUdpPacket(a8::UdpPacket* pkt)
{
#if 0
f8::UdpLog::Instance()->Debug("ProcUdpPacket host:%s port:%d buflen:%d",
{
inet_ntoa(pkt->remote_addr.sin_addr),
pkt->remote_addr.sin_port,
pkt->buf_len
});
#endif
const int IKCP_OVERHEAD = 24;
if (pkt->buf_len < IKCP_OVERHEAD) {
f8::UdpLog::Instance()->Warning("ProcUdpPacket host:%s port:%d buflen:%d over_head_error",
{
inet_ntoa(pkt->remote_addr.sin_addr),
pkt->remote_addr.sin_port,
pkt->buf_len
});
return;
}
int socket_handle = ikcp_getconv(pkt->buf);
auto session = GetSession(socket_handle);
if (!session) {
f8::UdpLog::Instance()->Warning("ProcUdpPacket host:%s socket_handle:%d session_error",
{
inet_ntoa(pkt->remote_addr.sin_addr),
pkt->remote_addr.sin_port,
socket_handle
});
return;
}
if (session->GetSecretKeyPlace()) {
if (pkt->buf_len >= IKCP_OVERHEAD + KcpSession::GetSecretKeyLen()) {
long long secret_key = KcpSession::ReadSecretKey(pkt->buf + IKCP_OVERHEAD, pkt->buf_len);
if (secret_key == session->GetKcpSession()->GetSecretKey()) {
session->GetKcpSession()->OnRecvPacket(pkt);
} else {
f8::UdpLog::Instance()->Warning("ProcUdpPacket host:%s port:%d socket_handle%d secret_key:%d secret_error",
{
inet_ntoa(pkt->remote_addr.sin_addr),
pkt->remote_addr.sin_port,
socket_handle,
secret_key
});
}
} else {
f8::UdpLog::Instance()->Warning("ProcUdpPacket host:%s port:%d buflen:%d bufflen_error",
{
inet_ntoa(pkt->remote_addr.sin_addr),
pkt->remote_addr.sin_port,
pkt->buf_len
});
}
} else {
session->GetKcpSession()->OnRecvPacket(pkt);
}
}
void LongSessionMgr::DelSession(int socket_handle)
{
{
auto session = GetSession(socket_handle);
if (session) {
if (session.use_count() != 2) {
#ifdef DEBUG
abort();
#endif
}
session->UnInit();
}
}
socket_handle_hash_.erase(socket_handle);
}
int LongSessionMgr::GetLongSessionCount()
{
return socket_handle_hash_.size();
}

View File

@ -0,0 +1,39 @@
#pragma once
#include <a8/singleton.h>
namespace a8
{
class UdpListener;
struct UdpPacket;
}
namespace ss
{
class SS_CMKcpHandshake;
}
class LongSession;
class LongSessionMgr : public a8::Singleton<LongSessionMgr>
{
private:
LongSessionMgr() {};
friend class a8::Singleton<LongSessionMgr>;
public:
void Init();
void UnInit();
void Update();
void _SS_CMKcpHandshake(f8::MsgHdr& hdr, const ss::SS_CMKcpHandshake& msg);
void ProcUdpPacket(a8::UdpPacket* pkt);
std::shared_ptr<LongSession> GetSession(int socket_handle);
std::shared_ptr<a8::UdpListener> GetUdpListener() { return udp_listener_; }
void DelSession(int socket_handle);
int GetLongSessionCount();
private:
std::shared_ptr<a8::UdpListener> udp_listener_;
std::map<int, std::shared_ptr<LongSession>> socket_handle_hash_;
};

160
server/wsproxy/master.cc Normal file
View File

@ -0,0 +1,160 @@
#include "precompile.h"
#include <string.h>
#include <a8/tcpclient.h>
#include <f8/udplog.h>
#include <f8/timer.h>
#include "ss_proto.pb.h"
#include "ss_msgid.pb.h"
#include "master.h"
#include "app.h"
const int PACK_MAX = 1024 * 64;
void Master::Init(int instance_id, const std::string& remote_ip, int remote_port)
{
this->instance_id = instance_id;
this->remote_ip = remote_ip;
this->remote_port = remote_port;
recv_bufflen_ = 0;
last_pong_tick = a8::XGetTickCount();
recv_buff_ = (char*) malloc(PACK_MAX * 2);
tcp_client_ = std::make_shared<a8::TcpClient>();
tcp_client_->remote_address = remote_ip;
tcp_client_->remote_port = remote_port;
tcp_client_->on_error = std::bind(&Master::on_error, this, std::placeholders::_1, std::placeholders::_2);
tcp_client_->on_connect = std::bind(&Master::on_connect, this, std::placeholders::_1);
tcp_client_->on_disconnect = std::bind(&Master::on_disconnect, this, std::placeholders::_1);
tcp_client_->on_socketread = std::bind(&Master::on_socketread, this ,std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
timer_wp_ = f8::Timer::Instance()->SetIntervalWpEx
(1000 * 9 + a8::RandEx(500, 150),
[this] (int event, const a8::Args* args)
{
if (a8::TIMER_EXEC_EVENT == event) {
CheckAlive();
}
},
&attacher_);
}
void Master::UnInit()
{
if (!timer_wp_.expired()) {
f8::Timer::Instance()->Delete(timer_wp_);
}
tcp_client_->Close();
if (tcp_client_.use_count() != 1) {
abort();
}
tcp_client_ = nullptr;
recv_bufflen_ = 0;
free(recv_buff_);
recv_buff_ = nullptr;
}
void Master::Open()
{
tcp_client_->Open();
}
void Master::Close()
{
tcp_client_->Close();
}
bool Master::Connected()
{
return tcp_client_->Connected();
}
void Master::on_error(a8::TcpClient* sender, int errorId)
{
f8::UdpLog::Instance()->Error("Master errorid=%d remote_ip:%s remote_port:%d",
{
errorId,
sender->remote_address,
sender->remote_port
});
}
void Master::on_connect(a8::TcpClient* sender)
{
recv_bufflen_ = 0;
f8::UdpLog::Instance()->Info("masterserver connected", {});
}
void Master::on_disconnect(a8::TcpClient* sender)
{
recv_bufflen_ = 0;
f8::UdpLog::Instance()->Info("masterserver %d disconnected after 10s later reconnect", {instance_id});
}
void Master::on_socketread(a8::TcpClient* sender, char* buf, unsigned int len)
{
#if 0
++App::Instance()->perf.read_count;
#endif
if (recv_bufflen_ + len > 2 * PACK_MAX) {
recv_bufflen_ = 0;
f8::UdpLog::Instance()->Debug("recvied masterserver too long message", {});
return;
} else {
memmove(&recv_buff_[recv_bufflen_], buf, len);
recv_bufflen_ += len;
}
bool warning = false;
unsigned int offset = 0;
while (recv_bufflen_ - offset >= sizeof(f8::PackHead)) {
f8::PackHead* p = (f8::PackHead*) &recv_buff_[offset];
if (p->magic_code == f8::MAGIC_CODE) {
if (recv_bufflen_ - offset < sizeof(f8::PackHead) + p->packlen) {
break;
}
App::Instance()->AddSocketMsg(SF_MasterServer,
0,
instance_id,
p->msgid,
p->seqid,
&recv_buff_[offset + sizeof(f8::PackHead)],
p->packlen);
offset += sizeof(f8::PackHead) + p->packlen;
} else {
warning = true;
offset++;
continue;
}
}
if (warning) {
f8::UdpLog::Instance()->Debug("recvied bad package", {});
}
if (offset > 0 && offset < recv_bufflen_) {
memmove(recv_buff_, recv_buff_ + offset, recv_bufflen_ - offset);
}
recv_bufflen_ -= offset;
#if 1
last_pong_tick = a8::XGetTickCount();
#endif
}
void Master::CheckAlive()
{
if (!Connected()) {
Open();
} else {
if (a8::XGetTickCount() - last_pong_tick > 60 * 10 * 1000) {
last_pong_tick = a8::XGetTickCount();
Close();
Open();
} else {
ss::SS_Ping msg;
SendMsg(msg);
}
}
}

View File

@ -1,15 +1,13 @@
#pragma once
#include "framework/cpp/protoutils.h"
#include <f8/protoutils.h>
namespace a8
{
class TcpClient;
class AsyncTcpClient;
}
struct timer_list;
class MasterSvr
class Master
{
public:
int instance_id = 0;
@ -29,31 +27,21 @@ class MasterSvr
void SendMsg(T& msg)
{
static int msgid = f8::Net_GetMessageId(msg);
f8::Net_SendMsg(tcp_client_, 0, msgid, msg);
f8::Net_SendMsg(tcp_client_.get(), 0, msgid, msg);
}
private:
#if ASYNC_TCPCLIENT
void on_error(a8::AsyncTcpClient* sender, int errorId);
void on_connect(a8::AsyncTcpClient* sender);
void on_disconnect(a8::AsyncTcpClient* sender);
void on_socketread(a8::AsyncTcpClient* sender, char* buf, unsigned int len);
#else
void on_error(a8::TcpClient* sender, int errorId);
void on_connect(a8::TcpClient* sender);
void on_disconnect(a8::TcpClient* sender);
void on_socketread(a8::TcpClient* sender, char* buf, unsigned int len);
#endif
void CheckAlive();
private:
char *recv_buff_ = nullptr;
unsigned int recv_bufflen_ = 0;
#if ASYNC_TCPCLIENT
a8::AsyncTcpClient* tcp_client_ = nullptr;
#else
a8::TcpClient* tcp_client_ = nullptr;
#endif
timer_list* timer_ = nullptr;
std::shared_ptr<a8::TcpClient> tcp_client_;
f8::TimerWp timer_wp_;
f8::Attacher attacher_;
};

201
server/wsproxy/mastermgr.cc Normal file
View File

@ -0,0 +1,201 @@
#include "precompile.h"
#include <unistd.h>
#include <a8/openssl.h>
#include <f8/timer.h>
#include <f8/netmsghandler.h>
#include <f8/protoutils.h>
#include "mastermgr.h"
#include "master.h"
#include "jsondatamgr.h"
#include "ss_proto.pb.h"
#include "upstream.h"
#include "upstreammgr.h"
#include "app.h"
#include "downstreammgr.h"
#include "GCListener.h"
class RequestTarget
{
public:
long long context_id = 0;
int socket_handle = 0;
std::string account_id;
f8::MsgHdr* hdr_copy = nullptr;
f8::TimerWp timer_wp;
long long req_tick = 0;
std::weak_ptr<UpStream> conn;
};
void MasterMgr::Init()
{
curr_context_id_ = a8::MakeInt64(0, time(nullptr) + 1000 * 60 * 10);
JsonDataMgr::Instance()->TraverseMaster
(
[this] (int instance_id, std::string remote_ip, int remote_port)
{
auto conn = std::make_shared<Master>();
conn->Init(instance_id, remote_ip, remote_port);
mastersvr_hash_[conn->instance_id] = conn;
conn->Open();
});
}
void MasterMgr::UnInit()
{
for (auto& pair : mastersvr_hash_) {
pair.second->UnInit();
}
mastersvr_hash_.clear();
}
void MasterMgr::_SS_MS_ResponseTargetServer(f8::MsgHdr& hdr, const ss::SS_MS_ResponseTargetServer& msg)
{
auto req = GetRequestByContextId(msg.context_id());
if (req) {
if (msg.error_code() == 0) {
std::weak_ptr<UpStream> conn = UpStreamMgr::Instance()->RecreateUpStream
(
msg.host(),
msg.port()
);
if (!conn.expired()) {
conn.lock()->ForwardClientMsgEx(req->hdr_copy);
req->conn = conn;
req->hdr_copy = nullptr;
if (!req->timer_wp.expired()) {
f8::Timer::Instance()->FireEvent(req->timer_wp,
ALLOC_TARGET_SERVER_SUCCESS_TIMER_EVENT,
nullptr);
f8::Timer::Instance()->Delete(req->timer_wp);
}
RemoveRequest(req->socket_handle);
return;
} else {
abort();
}
} else {
RemoveRequest(req->socket_handle);
}
}
}
std::shared_ptr<Master> MasterMgr::GetConnById(int instance_id)
{
auto itr = mastersvr_hash_.find(instance_id);
return itr != mastersvr_hash_.end() ? itr->second : nullptr;
}
void MasterMgr::RequestTargetServer(f8::MsgHdr& hdr,
const std::string& team_id,
const std::string& account_id,
const std::string& session_id,
const std::string& server_info,
int is_reconnect,
int proto_version)
{
if (GetRequestBySocket(hdr.socket_handle)) {
return;
}
unsigned int code = 0;
std::string team_uuid = team_id;
if (!team_id.empty()) {
code = a8::openssl::Crc32((unsigned char*)team_id.data(), team_id.size());
} else {
std::string data = a8::Format("!%s_%s_%d_%d",
{
account_id,
App::Instance()->NewUuid(),
getpid(),
rand()
});
team_uuid = data;
code = a8::openssl::Crc32((unsigned char*)data.data(), data.size());
}
std::shared_ptr<Master> svr = GetConnById(code % mastersvr_hash_.size() + 1);
if (svr) {
++curr_context_id_;
auto req = std::make_shared<RequestTarget>();
req->context_id = curr_context_id_;
req->socket_handle = hdr.socket_handle;
req->account_id = account_id;
req->req_tick = a8::XGetTickCount();
req->hdr_copy = hdr.Clone();
ss::SS_WSP_RequestTargetServer msg;
msg.set_context_id(curr_context_id_);
msg.set_account_id(account_id);
msg.set_session_id(session_id);
msg.set_team_id(team_uuid);
msg.set_server_info(server_info);
msg.set_is_reconnect(is_reconnect);
msg.set_proto_version(proto_version);
#ifdef DEBUG
std::string url;
std::string query_str;
{
GCListener::Instance()->GetWebSocketUrl(hdr.socket_handle, url, query_str);
}
msg.set_url(url);
msg.set_query_str(query_str);
#endif
svr->SendMsg(msg);
pending_socket_hash_[hdr.socket_handle] = req;
assert(pending_context_hash_.find(curr_context_id_) == pending_context_hash_.end());
pending_context_hash_[curr_context_id_] = req;
req->timer_wp = f8::Timer::Instance()->SetTimeoutWp
(1000 * 10,
[req] (int event, const a8::Args* args)
{
if (a8::TIMER_EXEC_EVENT == event) {
MasterMgr::Instance()->RemoveRequest
(
req->socket_handle
);
long long req_handle_time = a8::XGetTickCount() - req->req_tick;
if (req_handle_time > App::Instance()->GetPerf().max_login_time) {
App::Instance()->GetPerf().max_login_time = req_handle_time;
}
DownStreamMgr::Instance()->AddPendingAccount(req->account_id, req->socket_handle, req->req_tick);
} else if (ALLOC_TARGET_SERVER_SUCCESS_TIMER_EVENT == event) {
long long req_handle_time = a8::XGetTickCount() - req->req_tick;
if (req_handle_time > App::Instance()->GetPerf().max_login_time) {
App::Instance()->GetPerf().max_login_time = req_handle_time;
}
DownStreamMgr::Instance()->AddPendingAccount(req->account_id, req->socket_handle, req->req_tick);
}
}
);
}
}
void MasterMgr::RemoveRequest(int socket_handle)
{
auto req = GetRequestBySocket(socket_handle);
if (req) {
if (req->hdr_copy) {
f8::MsgHdr::Destroy(req->hdr_copy);
req->hdr_copy = nullptr;
}
pending_context_hash_.erase(req->context_id);
pending_socket_hash_.erase(socket_handle);
}
}
std::shared_ptr<RequestTarget> MasterMgr::GetRequestBySocket(int socket_handle)
{
auto itr = pending_socket_hash_.find(socket_handle);
return itr != pending_socket_hash_.end() ? itr->second : nullptr;
}
std::shared_ptr<RequestTarget> MasterMgr::GetRequestByContextId(long long context_id)
{
auto itr = pending_context_hash_.find(context_id);
return itr != pending_context_hash_.end() ? itr->second : nullptr;
}

View File

@ -0,0 +1,50 @@
#pragma once
namespace f8
{
struct MsgHdr;
}
namespace ss
{
class SS_MS_ResponseTargetServer;
}
class RequestTarget;
class Master;
class MasterMgr : public a8::Singleton<MasterMgr>
{
public:
enum { HID = HID_MasterMgr };
private:
MasterMgr() {};
friend class a8::Singleton<MasterMgr>;
public:
void Init();
void UnInit();
void _SS_MS_ResponseTargetServer(f8::MsgHdr& hdr, const ss::SS_MS_ResponseTargetServer& msg);
void RequestTargetServer(f8::MsgHdr& hdr,
const std::string& team_id,
const std::string& account_id,
const std::string& session_id,
const std::string& server_info,
int is_reconnect,
int proto_version);
void RemoveRequest(int socket_handle);
private:
std::shared_ptr<RequestTarget> GetRequestBySocket(int socket_handle);
std::shared_ptr<RequestTarget> GetRequestByContextId(long long context_id);
std::shared_ptr<Master> GetConnById(int instance_id);
private:
long long curr_context_id_ = 0;
std::map<int, std::shared_ptr<Master>> mastersvr_hash_;
std::map<int, std::shared_ptr<RequestTarget>> pending_socket_hash_;
std::map<long long, std::shared_ptr<RequestTarget>> pending_context_hash_;
};

View File

@ -1,182 +0,0 @@
#include "precompile.h"
#include <string.h>
#include "ss_proto.pb.h"
#include "ss_msgid.pb.h"
#include "mastersvr.h"
#include <a8/tcpclient.h>
#include <a8/asynctcpclient.h>
#include <a8/ioloop.h>
#include <a8/udplog.h>
#include <a8/timer.h>
#include "app.h"
const int PACK_MAX = 1024 * 64;
void MasterSvr::Init(int instance_id, const std::string& remote_ip, int remote_port)
{
this->instance_id = instance_id;
this->remote_ip = remote_ip;
this->remote_port = remote_port;
recv_bufflen_ = 0;
last_pong_tick = a8::XGetTickCount();
recv_buff_ = (char*) malloc(PACK_MAX * 2);
#if ASYNC_TCPCLIENT
tcp_client_ = a8::IoLoop::Instance()->CreateAsyncTcpClient();
#else
tcp_client_ = new a8::TcpClient();
#endif
tcp_client_->remote_address = remote_ip;
tcp_client_->remote_port = remote_port;
tcp_client_->on_error = std::bind(&MasterSvr::on_error, this, std::placeholders::_1, std::placeholders::_2);
tcp_client_->on_connect = std::bind(&MasterSvr::on_connect, this, std::placeholders::_1);
tcp_client_->on_disconnect = std::bind(&MasterSvr::on_disconnect, this, std::placeholders::_1);
tcp_client_->on_socketread = std::bind(&MasterSvr::on_socketread, this ,std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
timer_ = a8::Timer::Instance()->AddRepeatTimer(1000 * 9 + a8::RandEx(500, 150),
a8::XParams().SetSender(this),
[] (const a8::XParams& param)
{
MasterSvr* conn = (MasterSvr*)param.sender.GetUserData();
conn->CheckAlive();
});
}
void MasterSvr::UnInit()
{
a8::Timer::Instance()->DeleteTimer(timer_);
timer_ = nullptr;
tcp_client_->Close();
#if ASYNC_TCPCLIENT
a8::IoLoop::Instance()->DestoryAsyncTcpClient(tcp_client_);
#else
delete tcp_client_;
#endif
tcp_client_ = nullptr;
recv_bufflen_ = 0;
free(recv_buff_);
recv_buff_ = nullptr;
}
void MasterSvr::Open()
{
tcp_client_->Open();
}
void MasterSvr::Close()
{
tcp_client_->Close();
}
bool MasterSvr::Connected()
{
return tcp_client_->Connected();
}
#if ASYNC_TCPCLIENT
void MasterSvr::on_error(a8::AsyncTcpClient* sender, int errorId)
#else
void MasterSvr::on_error(a8::TcpClient* sender, int errorId)
#endif
{
a8::UdpLog::Instance()->Error("MasterSvr errorid=%d remote_ip:%s remote_port:%d",
{
errorId,
sender->remote_address,
sender->remote_port
});
}
#if ASYNC_TCPCLIENT
void MasterSvr::on_connect(a8::AsyncTcpClient* sender)
#else
void MasterSvr::on_connect(a8::TcpClient* sender)
#endif
{
recv_bufflen_ = 0;
a8::UdpLog::Instance()->Info("masterserver connected", {});
}
#if ASYNC_TCPCLIENT
void MasterSvr::on_disconnect(a8::AsyncTcpClient* sender)
#else
void MasterSvr::on_disconnect(a8::TcpClient* sender)
#endif
{
recv_bufflen_ = 0;
a8::UdpLog::Instance()->Info("masterserver %d disconnected after 10s later reconnect", {instance_id});
App::Instance()->AddIMMsg(IM_MasterSvrDisconnect,
a8::XParams()
.SetSender(instance_id)
);
}
#if ASYNC_TCPCLIENT
void MasterSvr::on_socketread(a8::AsyncTcpClient* sender, char* buf, unsigned int len)
#else
void MasterSvr::on_socketread(a8::TcpClient* sender, char* buf, unsigned int len)
#endif
{
#if 0
++App::Instance()->perf.read_count;
#endif
if (recv_bufflen_ + len > 2 * PACK_MAX) {
recv_bufflen_ = 0;
a8::UdpLog::Instance()->Debug("recvied masterserver too long message", {});
return;
} else {
memmove(&recv_buff_[recv_bufflen_], buf, len);
recv_bufflen_ += len;
}
bool warning = false;
unsigned int offset = 0;
while (recv_bufflen_ - offset >= sizeof(f8::PackHead)) {
f8::PackHead* p = (f8::PackHead*) &recv_buff_[offset];
if (p->magic_code == f8::MAGIC_CODE) {
if (recv_bufflen_ - offset < sizeof(f8::PackHead) + p->packlen) {
break;
}
App::Instance()->AddSocketMsg(SF_MasterServer,
0,
instance_id,
p->msgid,
p->seqid,
&recv_buff_[offset + sizeof(f8::PackHead)],
p->packlen);
offset += sizeof(f8::PackHead) + p->packlen;
} else {
warning = true;
offset++;
continue;
}
}
if (warning) {
a8::UdpLog::Instance()->Debug("recvied bad package", {});
}
if (offset > 0 && offset < recv_bufflen_) {
memmove(recv_buff_, recv_buff_ + offset, recv_bufflen_ - offset);
}
recv_bufflen_ -= offset;
#if 1
last_pong_tick = a8::XGetTickCount();
#endif
}
void MasterSvr::CheckAlive()
{
if (!Connected()) {
Open();
} else {
if (a8::XGetTickCount() - last_pong_tick > 60 * 10 * 1000) {
last_pong_tick = a8::XGetTickCount();
Close();
Open();
} else {
ss::SS_Ping msg;
SendMsg(msg);
}
}
}

View File

@ -1,208 +0,0 @@
#include "precompile.h"
#include <unistd.h>
#include <a8/openssl.h>
#include <a8/timer.h>
#include "mastersvrmgr.h"
#include "mastersvr.h"
#include "jsondatamgr.h"
#include "ss_proto.pb.h"
#include "target_conn.h"
#include "target_conn_mgr.h"
#include "app.h"
#include "gameclientmgr.h"
#include "framework/cpp/netmsghandler.h"
void MasterSvrMgr::Init()
{
curr_context_id_ = a8::MakeInt64(0, time(nullptr) + 1000 * 60 * 10);
#if MASTER_MODE
auto master_svr_cluster_conf = JsonDataMgr::Instance()->GetMasterServerClusterConf();
for (int i = 0; i < master_svr_cluster_conf->Size(); ++i) {
auto master_svr_conf = master_svr_cluster_conf->At(i);
int instance_id = master_svr_conf->At("instance_id")->AsXValue();
std::string remote_ip = master_svr_conf->At("ip")->AsXValue();
int remote_port = master_svr_conf->At("port")->AsXValue();
{
MasterSvr* conn = new MasterSvr();
conn->Init(instance_id, remote_ip, remote_port);
mastersvr_hash_[conn->instance_id] = conn;
conn->Open();
}
}
#endif
}
void MasterSvrMgr::UnInit()
{
}
void MasterSvrMgr::_SS_MS_ResponseTargetServer(f8::MsgHdr& hdr, const ss::SS_MS_ResponseTargetServer& msg)
{
f8::MsgHdr* context_hdr = GetHdrByContextId(msg.context_id());
if (context_hdr) {
int socket_handle = context_hdr->socket_handle;
if (msg.error_code() == 0) {
TargetConn* conn = TargetConnMgr::Instance()->RecreateTargetConn(
msg.host(),
msg.port()
);
assert(conn);
if (conn) {
RemoveRequest(socket_handle, msg.context_id(), false);
conn->ForwardClientMsgEx(context_hdr);
return;
}
}
RemoveRequest(socket_handle, msg.context_id(), true);
}
}
MasterSvr* MasterSvrMgr::GetConnById(int instance_id)
{
auto itr = mastersvr_hash_.find(instance_id);
return itr != mastersvr_hash_.end() ? itr->second : nullptr;
}
void MasterSvrMgr::RequestTargetServer(f8::MsgHdr& hdr,
const std::string& team_id,
const std::string& account_id,
const std::string& server_info,
int is_reconnect,
int proto_version)
{
#if GAME_ID == 9003
{
TargetConn* conn = TargetConnMgr::Instance()->RecreateTargetConn(
"10.10.4.4",
8951
);
if (conn) {
f8::MsgHdr* new_hdr = hdr.Clone();
conn->ForwardClientMsgEx(new_hdr);
return;
} else {
abort();
}
}
#endif
if (GetContextIdBySocket(hdr.socket_handle) != 0) {
return;
}
unsigned int code = 0;
std::string team_uuid = team_id;
if (!team_id.empty()) {
code = a8::openssl::Crc32((unsigned char*)team_id.data(), team_id.size());
} else {
std::string data = a8::Format("!%s_%s_%d_%d",
{
account_id,
App::Instance()->uuid.Generate(),
getpid(),
rand()
});
team_uuid = data;
code = a8::openssl::Crc32((unsigned char*)data.data(), data.size());
}
MasterSvr* svr = GetConnById(code % mastersvr_hash_.size() + 1);
if (svr) {
++curr_context_id_;
a8::TimerAttacher* timer_attacher = new a8::TimerAttacher();
f8::MsgHdr* new_hdr = hdr.Clone();
new_hdr->user_data = timer_attacher;
ss::SS_WSP_RequestTargetServer msg;
msg.set_context_id(curr_context_id_);
msg.set_account_id(account_id);
msg.set_team_id(team_uuid);
msg.set_server_info(server_info);
msg.set_is_reconnect(is_reconnect);
msg.set_proto_version(proto_version);
svr->SendMsg(msg);
pending_socket_hash_[hdr.socket_handle] = curr_context_id_;
assert(pending_request_hash_.find(curr_context_id_) == pending_request_hash_.end());
pending_request_hash_[curr_context_id_] = new_hdr;
if (account_id == azw_account_id) {
a8::UdpLog::Instance()->Info("%s request", {account_id});
}
auto timer_func =
[] (const a8::XParams& param)
{
if (param.param2.GetString() == azw_account_id) {
a8::UdpLog::Instance()->Info("%s timeout",
{
param.param2.GetString()
});
}
a8::Timer::Instance()->RemoveTimerAfterFunc(a8::Timer::Instance()->GetRunningTimer());
MasterSvrMgr::Instance()->RemoveRequest(
param.param1,
param.sender,
true
);
};
auto timer_after_func =
[] (const a8::XParams& param)
{
if (param.param2.GetString() == azw_account_id) {
a8::UdpLog::Instance()->Info("%s response time:%d",
{
param.param2.GetString(),
a8::XGetTickCount() - param.param3.GetInt64()
});
}
long long req_handle_time = a8::XGetTickCount() - param.param3.GetInt64();
if (req_handle_time > App::Instance()->perf.max_login_time) {
App::Instance()->perf.max_login_time = req_handle_time;
}
GameClientMgr::Instance()->AddPendingAccount(param.param2.GetString(), param.param1, param.param3);
};
a8::Timer::Instance()->AddDeadLineTimerAndAttach(1000 * 10,
a8::XParams()
.SetSender(curr_context_id_)
.SetParam1(hdr.socket_handle)
.SetParam2(account_id)
.SetParam3(a8::XGetTickCount()),
timer_func,
&timer_attacher->timer_list_,
timer_after_func
);
}
}
void MasterSvrMgr::RemoveRequest(int socket_handle, long long context_id, bool auto_free)
{
if (context_id == GetContextIdBySocket(socket_handle)) {
f8::MsgHdr* hdr = GetHdrByContextId(context_id);
if (hdr) {
a8::TimerAttacher* timer_attacher = (a8::TimerAttacher*)hdr->user_data;
delete timer_attacher;
hdr->user_data = nullptr;
if (auto_free) {
if (hdr->buf) {
free((char*)hdr->buf);
}
free(hdr);
}
}
pending_request_hash_.erase(context_id);
pending_socket_hash_.erase(socket_handle);
}
}
long long MasterSvrMgr::GetContextIdBySocket(int socket_handle)
{
auto itr = pending_socket_hash_.find(socket_handle);
return itr != pending_socket_hash_.end() ? itr->second : 0;
}
f8::MsgHdr* MasterSvrMgr::GetHdrByContextId(long long context_id)
{
auto itr = pending_request_hash_.find(context_id);
return itr != pending_request_hash_.end() ? itr->second : nullptr;
}

View File

@ -1,49 +0,0 @@
#pragma once
namespace f8
{
struct MsgHdr;
}
namespace ss
{
class SS_MS_ResponseTargetServer;
}
class MasterSvr;
class MasterSvrMgr : public a8::Singleton<MasterSvrMgr>
{
public:
enum { HID = HID_MasterSvrMgr };
private:
MasterSvrMgr() {};
friend class a8::Singleton<MasterSvrMgr>;
public:
void Init();
void UnInit();
void _SS_MS_ResponseTargetServer(f8::MsgHdr& hdr, const ss::SS_MS_ResponseTargetServer& msg);
void RequestTargetServer(f8::MsgHdr& hdr,
const std::string& team_id,
const std::string& account_id,
const std::string& server_info,
int is_reconnect,
int proto_version);
void RemoveRequest(int socket_handle, long long context_id, bool auto_free);
private:
long long GetContextIdBySocket(int socket_handle);
f8::MsgHdr* GetHdrByContextId(long long context_id);
MasterSvr* GetConnById(int instance_id);
private:
int target_conn_id_ = 100;
long long curr_context_id_ = 0;
std::map<int, MasterSvr*> mastersvr_hash_;
std::map<int, long long> pending_socket_hash_;
std::map<long long, f8::MsgHdr*> pending_request_hash_;
};

View File

@ -1,20 +1,8 @@
#pragma once
#include <a8/a8.h>
#include <a8/udplog.h>
#include <f8/f8.h>
#include <f8/timer.h>
#include "constant.h"
#include "types.h"
namespace google
{
namespace protobuf
{
class Message;
}
}
#include "framework/cpp/types.h"
#include "framework/cpp/utils.h"
#include "framework/cpp/protoutils.h"

View File

@ -1,72 +0,0 @@
#include "precompile.h"
#include "target_conn_mgr.h"
#include "target_conn.h"
#include "jsondatamgr.h"
#include "app.h"
void TargetConnMgr::Init()
{
#if MASTER_MODE
#else
auto target_server_cluster_conf = JsonDataMgr::Instance()->GetTargetServerClusterConf();
for (int i = 0; i < target_server_cluster_conf->Size(); ++i) {
auto target_server_conf = target_server_cluster_conf->At(i);
int instance_id = target_server_conf->At("instance_id")->AsXValue();
std::string remote_ip = target_server_conf->At("ip")->AsXValue();
int remote_port = target_server_conf->At("port")->AsXValue();
if (App::Instance()->HasFlag(3)) {
remote_ip = "127.0.0.1";
}
{
TargetConn* conn = new TargetConn();
conn->Init(instance_id, remote_ip, remote_port);
id_hash_[conn->instance_id] = conn;
conn->Open();
}
if (App::Instance()->HasFlag(3)) {
break;
}
}
#endif
}
void TargetConnMgr::UnInit()
{
for (auto& pair : id_hash_) {
pair.second->UnInit();
delete pair.second;
}
}
TargetConn* TargetConnMgr::GetConnByKey(const std::string& key)
{
auto itr = key_hash_.find(key);
return itr != key_hash_.end() ? itr->second : nullptr;
}
TargetConn* TargetConnMgr::GetConnById(int instance_id)
{
auto itr = id_hash_.find(instance_id);
return itr != id_hash_.end() ? itr->second : nullptr;
}
TargetConn* TargetConnMgr::RecreateTargetConn(const std::string& host, int port)
{
std::string key = host + ":" + a8::XValue(port).GetString();
TargetConn* conn = GetConnByKey(key);
if (conn) {
return conn;
}
while (GetConnById(++curr_id_)) {};
int instance_id = curr_id_;
std::string remote_ip = host;
int remote_port = port;
conn = new TargetConn();
conn->Init(instance_id, remote_ip, remote_port);
id_hash_[conn->instance_id] = conn;
key_hash_[key] = conn;
conn->Open();
return conn;
}

View File

@ -1,23 +0,0 @@
#pragma once
class TargetConn;
class TargetConnMgr : public a8::Singleton<TargetConnMgr>
{
private:
TargetConnMgr() {};
friend class a8::Singleton<TargetConnMgr>;
public:
void Init();
void UnInit();
TargetConn* GetConnByKey(const std::string& key);
TargetConn* GetConnById(int instance_id);
TargetConn* RecreateTargetConn(const std::string& host, int port);
private:
unsigned short curr_id_ = 1000;
std::map<std::string, TargetConn*> key_hash_;
std::map<int, TargetConn*> id_hash_;
};

View File

@ -2,19 +2,21 @@
#include <string.h>
#include <a8/tcpclient.h>
#include <f8/udplog.h>
#include <f8/timer.h>
#include <f8/msgqueue.h>
#include "ss_proto.pb.h"
#include "ss_msgid.pb.h"
#include "target_conn.h"
#include <a8/tcpclient.h>
#include <a8/udplog.h>
#include <a8/timer.h>
#include <a8/ioloop.h>
#include <a8/asynctcpclient.h>
#include "upstream.h"
#include "app.h"
const int PACK_MAX = 1024 * 64 * 2;
void TargetConn::Init(int instance_id, const std::string& remote_ip, int remote_port)
void UpStream::Init(int instance_id, const std::string& remote_ip, int remote_port)
{
if (remote_ip.empty()) {
abort();
@ -26,94 +28,88 @@ void TargetConn::Init(int instance_id, const std::string& remote_ip, int remote_
recv_bufflen_ = 0;
last_pong_tick = a8::XGetTickCount();
recv_buff_ = (char*) malloc(PACK_MAX * 2);
#if ASYNC_TCPCLIENT && GAME_ID == 2002
tcp_client_ = a8::IoLoop::Instance()->CreateAsyncTcpClient();
#else
tcp_client_ = new a8::TcpClient();
#endif
tcp_client_ = std::make_shared<a8::TcpClient>();
tcp_client_->remote_address = remote_ip;
tcp_client_->remote_port = remote_port;
tcp_client_->on_error = std::bind(&TargetConn::on_error, this, std::placeholders::_1, std::placeholders::_2);
tcp_client_->on_connect = std::bind(&TargetConn::on_connect, this, std::placeholders::_1);
tcp_client_->on_disconnect = std::bind(&TargetConn::on_disconnect, this, std::placeholders::_1);
tcp_client_->on_socketread = std::bind(&TargetConn::on_socketread, this ,std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
timer_ = a8::Timer::Instance()->AddRepeatTimer(1000 * 9 + a8::RandEx(500, 150),
a8::XParams().SetSender(this),
[] (const a8::XParams& param)
{
TargetConn* conn = (TargetConn*)param.sender.GetUserData();
conn->CheckAlive();
});
tcp_client_->on_error = std::bind(&UpStream::on_error, this, std::placeholders::_1, std::placeholders::_2);
tcp_client_->on_connect = std::bind(&UpStream::on_connect, this, std::placeholders::_1);
tcp_client_->on_disconnect = std::bind(&UpStream::on_disconnect, this, std::placeholders::_1);
tcp_client_->on_socketread = std::bind(&UpStream::on_socketread, this ,std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
timer_wp_ = f8::Timer::Instance()->SetIntervalWpEx
(1000 * 9 + a8::RandEx(500, 150),
[this] (int event, const a8::Args* args)
{
if (a8::TIMER_EXEC_EVENT == event) {
CheckAlive();
}
},
&attacher_);
}
void TargetConn::UnInit()
void UpStream::UnInit()
{
TargetConnMsgNode* work_node;
UpStreamMsgNode* work_node;
work_node = top_node_;
top_node_ = nullptr;
bot_node_ = nullptr;
while (work_node) {
TargetConnMsgNode* pdelnode = work_node;
UpStreamMsgNode* pdelnode = work_node;
work_node = work_node->next_node;
delete pdelnode->msg;
delete pdelnode;
}
a8::Timer::Instance()->DeleteTimer(timer_);
timer_ = nullptr;
if (!timer_wp_.expired()) {
f8::Timer::Instance()->Delete(timer_wp_);
}
tcp_client_->Close();
#if ASYNC_TCPCLIENT && GAME_ID == 2002
a8::IoLoop::Instance()->DestoryAsyncTcpClient(tcp_client_);
#else
delete tcp_client_;
#endif
tcp_client_ = nullptr;
if(tcp_client_.use_count() != 1) {
abort();
}
recv_bufflen_ = 0;
free(recv_buff_);
recv_buff_ = nullptr;
}
void TargetConn::Open()
void UpStream::Open()
{
tcp_client_->Open();
}
void TargetConn::Close()
void UpStream::Close()
{
tcp_client_->Close();
}
bool TargetConn::Connected()
bool UpStream::Connected()
{
return tcp_client_->Connected();
}
void TargetConn::SendStockMsg()
void UpStream::SendStockMsg()
{
TargetConnMsgNode* work_node;
UpStreamMsgNode* work_node;
work_node = top_node_;
top_node_ = nullptr;
bot_node_ = nullptr;
while (work_node) {
TargetConnMsgNode* pdelnode = work_node;
UpStreamMsgNode* pdelnode = work_node;
work_node = work_node->next_node;
if (pdelnode->msg) {
f8::Net_SendProxyCMsg(tcp_client_, pdelnode->socket_handle, pdelnode->msgid, *pdelnode->msg);
f8::Net_SendProxyCMsg(tcp_client_.get(), pdelnode->socket_handle, pdelnode->msgid, *pdelnode->msg);
delete pdelnode->msg;
}
if (pdelnode->hdr) {
ForwardClientMsg(*pdelnode->hdr);
if (pdelnode->hdr->buf) {
free((char*)pdelnode->hdr->buf);
}
free(pdelnode->hdr);
f8::MsgHdr::Destroy(pdelnode->hdr);
pdelnode->hdr = nullptr;
}
delete pdelnode;
}
}
void TargetConn::ForwardClientMsg(f8::MsgHdr& hdr)
void UpStream::ForwardClientMsg(f8::MsgHdr& hdr)
{
char* buff = (char*)malloc(sizeof(f8::WSProxyPackHead_C) + hdr.buflen);
memset(buff, 0, sizeof(f8::WSProxyPackHead_C));
@ -136,7 +132,7 @@ void TargetConn::ForwardClientMsg(f8::MsgHdr& hdr)
free(buff);
}
void TargetConn::ForwardClientMsgEx(f8::MsgHdr* hdr)
void UpStream::ForwardClientMsgEx(f8::MsgHdr* hdr)
{
if (Connected()) {
if (top_node_) {
@ -152,13 +148,9 @@ void TargetConn::ForwardClientMsgEx(f8::MsgHdr* hdr)
}
}
#if ASYNC_TCPCLIENT && GAME_ID == 2002
void TargetConn::on_error(a8::AsyncTcpClient* sender, int errorId)
#else
void TargetConn::on_error(a8::TcpClient* sender, int errorId)
#endif
void UpStream::on_error(a8::TcpClient* sender, int errorId)
{
a8::UdpLog::Instance()->Error("target server errorid=%d remote_ip:%s remote_port:%d",
f8::UdpLog::Instance()->Error("target server errorid=%d remote_ip:%s remote_port:%d",
{
errorId,
sender->remote_address,
@ -166,56 +158,56 @@ void TargetConn::on_error(a8::TcpClient* sender, int errorId)
});
}
#if ASYNC_TCPCLIENT && GAME_ID == 2002
void TargetConn::on_connect(a8::AsyncTcpClient* sender)
#else
void TargetConn::on_connect(a8::TcpClient* sender)
#endif
void UpStream::on_connect(a8::TcpClient* sender)
{
recv_bufflen_ = 0;
a8::UdpLog::Instance()->Info("target server connected remote_ip:%s remote_port:%d",
f8::UdpLog::Instance()->Info("target server connected remote_ip:%s remote_port:%d",
{
sender->remote_address,
sender->remote_port
});
App::Instance()->AddIMMsg(IM_TargetConnConnect,
a8::XParams()
.SetSender(instance_id)
);
f8::MsgQueue::Instance()->PostMsg
(
IM_UpStreamConnect,
a8::Args
(
{
instance_id
}
)
);
}
#if ASYNC_TCPCLIENT && GAME_ID == 2002
void TargetConn::on_disconnect(a8::AsyncTcpClient* sender)
#else
void TargetConn::on_disconnect(a8::TcpClient* sender)
#endif
void UpStream::on_disconnect(a8::TcpClient* sender)
{
recv_bufflen_ = 0;
a8::UdpLog::Instance()->Info("target server %d disconnected after 10s later reconnect "
f8::UdpLog::Instance()->Info("target server %d disconnected after 10s later reconnect "
"remote_ip:%s remote_port:%d",
{
instance_id,
sender->remote_address,
sender->remote_port
});
App::Instance()->AddIMMsg(IM_TargetConnDisconnect,
a8::XParams()
.SetSender(instance_id)
);
f8::MsgQueue::Instance()->PostMsg
(
IM_UpStreamDisconnect,
a8::Args
(
{
instance_id
}
)
);
}
#if ASYNC_TCPCLIENT && GAME_ID == 2002
void TargetConn::on_socketread(a8::AsyncTcpClient* sender, char* buf, unsigned int len)
#else
void TargetConn::on_socketread(a8::TcpClient* sender, char* buf, unsigned int len)
#endif
void UpStream::on_socketread(a8::TcpClient* sender, char* buf, unsigned int len)
{
#if 0
++App::Instance()->perf.read_count;
#endif
if (recv_bufflen_ + len > 2 * PACK_MAX) {
recv_bufflen_ = 0;
a8::UdpLog::Instance()->Debug("recvied target server too long message", {});
f8::UdpLog::Instance()->Debug("recvied target server too long message", {});
return;
} else {
memmove(&recv_buff_[recv_bufflen_], buf, len);
@ -247,7 +239,7 @@ void TargetConn::on_socketread(a8::TcpClient* sender, char* buf, unsigned int le
}
if (warning) {
a8::UdpLog::Instance()->Debug("recvied bad package", {});
f8::UdpLog::Instance()->Debug("recvied bad package", {});
}
if (offset > 0 && offset < recv_bufflen_) {
memmove(recv_buff_, recv_buff_ + offset, recv_bufflen_ - offset);
@ -258,7 +250,7 @@ void TargetConn::on_socketread(a8::TcpClient* sender, char* buf, unsigned int le
#endif
}
void TargetConn::CheckAlive()
void UpStream::CheckAlive()
{
if (!Connected()) {
Open();
@ -273,10 +265,10 @@ void TargetConn::CheckAlive()
}
}
void TargetConn::AddStockMsg(unsigned short socket_handle, int msgid, ::google::protobuf::Message* msg,
void UpStream::AddStockMsg(unsigned short socket_handle, int msgid, ::google::protobuf::Message* msg,
f8::MsgHdr* hdr)
{
TargetConnMsgNode* node = new TargetConnMsgNode();
UpStreamMsgNode* node = new UpStreamMsgNode();
node->socket_handle = socket_handle;
node->msgid = msgid;
node->msg = msg;

View File

@ -1,25 +1,23 @@
#pragma once
#include "framework/cpp/protoutils.h"
#include <f8/protoutils.h>
namespace a8
{
class TcpClient;
class AsyncTcpClient;
}
struct TargetConnMsgNode
struct UpStreamMsgNode
{
unsigned short socket_handle = 0;
int msgid = 0;
::google::protobuf::Message* msg = nullptr;
f8::MsgHdr* hdr = nullptr;
TargetConnMsgNode* next_node = nullptr;
UpStreamMsgNode* next_node = nullptr;
};
struct timer_list;
class TargetConn
class UpStream
{
public:
int instance_id = 0;
@ -43,7 +41,7 @@ class TargetConn
if (top_node_) {
SendStockMsg();
}
f8::Net_SendProxyCMsg(tcp_client_, socket_handle, msgid, msg);
f8::Net_SendProxyCMsg(tcp_client_.get(), socket_handle, msgid, msg);
} else {
T* new_msg = new T();
*new_msg = msg;
@ -56,17 +54,10 @@ class TargetConn
void ForwardClientMsgEx(f8::MsgHdr* hdr);
private:
#if ASYNC_TCPCLIENT && GAME_ID == 2002
void on_error(a8::AsyncTcpClient* sender, int errorId);
void on_connect(a8::AsyncTcpClient* sender);
void on_disconnect(a8::AsyncTcpClient* sender);
void on_socketread(a8::AsyncTcpClient* sender, char* buf, unsigned int len);
#else
void on_error(a8::TcpClient* sender, int errorId);
void on_connect(a8::TcpClient* sender);
void on_disconnect(a8::TcpClient* sender);
void on_socketread(a8::TcpClient* sender, char* buf, unsigned int len);
#endif
void CheckAlive();
void AddStockMsg(unsigned short socket_handle, int msgid, ::google::protobuf::Message* msg,
@ -75,13 +66,10 @@ class TargetConn
private:
char *recv_buff_ = nullptr;
unsigned int recv_bufflen_ = 0;
#if ASYNC_TCPCLIENT && GAME_ID == 2002
a8::AsyncTcpClient* tcp_client_ = nullptr;
#else
a8::TcpClient* tcp_client_ = nullptr;
#endif
timer_list* timer_ = nullptr;
std::shared_ptr<a8::TcpClient> tcp_client_;
f8::TimerWp timer_wp_;
f8::Attacher attacher_;
TargetConnMsgNode* top_node_ = nullptr;
TargetConnMsgNode* bot_node_ = nullptr;
UpStreamMsgNode* top_node_ = nullptr;
UpStreamMsgNode* bot_node_ = nullptr;
};

View File

@ -0,0 +1,65 @@
#include "precompile.h"
#include <f8/msgqueue.h>
#include "upstreammgr.h"
#include "upstream.h"
void UpStreamMgr::Init()
{
f8::MsgQueue::Instance()->RegisterCallBack
(
IM_UpStreamConnect,
[this] (const a8::Args& args)
{
int instance_id = args.Get<int>(0);
std::weak_ptr<UpStream> up_wp = GetUpStreamById(instance_id);
if (!up_wp.expired() && up_wp.lock()->Connected()) {
up_wp.lock()->SendStockMsg();
}
});
f8::MsgQueue::Instance()->RegisterCallBack
(
IM_UpStreamDisconnect,
[this] (const a8::Args& args)
{
});
}
void UpStreamMgr::UnInit()
{
for (auto& pair : id_hash_) {
pair.second->UnInit();
}
}
std::weak_ptr<UpStream> UpStreamMgr::GetUpStreamByKey(const std::string& key)
{
auto itr = key_hash_.find(key);
return itr != key_hash_.end() ? itr->second : nullptr;
}
std::weak_ptr<UpStream> UpStreamMgr::GetUpStreamById(int instance_id)
{
auto itr = id_hash_.find(instance_id);
return itr != id_hash_.end() ? itr->second : nullptr;
}
std::weak_ptr<UpStream> UpStreamMgr::RecreateUpStream(const std::string& host, int port)
{
std::string key = host + ":" + a8::XValue(port).GetString();
if (!GetUpStreamByKey(key).expired()) {
return GetUpStreamByKey(key);
}
while (!GetUpStreamById(++curr_id_).expired()) {};
int instance_id = curr_id_;
std::string remote_ip = host;
int remote_port = port;
std::shared_ptr<UpStream> conn = std::make_shared<UpStream>();
conn->Init(instance_id, remote_ip, remote_port);
id_hash_[conn->instance_id] = conn;
key_hash_[key] = conn;
conn->Open();
return conn;
}

View File

@ -0,0 +1,25 @@
#pragma once
#include <a8/singleton.h>
class UpStream;
class UpStreamMgr : public a8::Singleton<UpStreamMgr>
{
private:
UpStreamMgr() {};
friend class a8::Singleton<UpStreamMgr>;
public:
void Init();
void UnInit();
std::weak_ptr<UpStream> GetUpStreamByKey(const std::string& key);
std::weak_ptr<UpStream> GetUpStreamById(int instance_id);
std::weak_ptr<UpStream> RecreateUpStream(const std::string& host, int port);
private:
unsigned short curr_id_ = 1000;
std::map<std::string, std::shared_ptr<UpStream>> key_hash_;
std::map<int, std::shared_ptr<UpStream>> id_hash_;
};

1
third_party/a8 vendored Submodule

@ -0,0 +1 @@
Subproject commit 1e577389c8a2870db9ddbf18577bfca24def049b

@ -1 +0,0 @@
Subproject commit a369c484113b240f042c62cba80afd26df91e4ca

@ -1 +1 @@
Subproject commit 240414570ee2848291d24ff8d3102dc43d4104a3
Subproject commit 8cd7e2432785bf4027e89c5dc74cb4980e4cd3c1

1
third_party/f8 vendored Submodule

@ -0,0 +1 @@
Subproject commit 243bbe515ef4a01089f9a6cf608c93d4097018de

@ -1 +0,0 @@
Subproject commit 9ba2696e52664c9f5b7a1e09a4a5516359d330b0

1
third_party/kcp vendored Submodule

@ -0,0 +1 @@
Subproject commit 10ee2b30c8739408c0db98211df4ebce7b01c0ed

@ -1 +1 @@
Subproject commit 35ca2eadc32161cd6ab479d1a2626759a73bb5a3
Subproject commit 0165dc279d62af5536f122ea30c3cd3f642f34ee

2
third_party/tools vendored

@ -1 +1 @@
Subproject commit 04a0bc939eeae0090fd0e8964dddf3863a551154
Subproject commit d38ce0b86c7b9262391f48108d808ddb62854760