void tryCompareConnect(unordered_map<int32_t, std::tuple<string, int>>& servers) { alreadyConnectingServersLock.lock(); for (auto& v : servers) { if (alreadyConnectingServers.find(v.first) == alreadyConnectingServers.end()) { int idInEtcd = v.first; string ip = std::get<0>(v.second); int port = std::get<1>(v.second); thread([ip, port, idInEtcd](){ gDailyLogger->info("ready connect connection server id:{}, addr :{}:{}", idInEtcd, ip, port); sock fd = ox_socket_connect(false, ip.c_str(), port); if (fd != SOCKET_ERROR) { gDailyLogger->info("connect success {}:{}", ip, port); WrapAddNetSession(gServer, fd, make_shared<UsePacketExtNetSession>(std::make_shared<ConnectionServerConnection>(idInEtcd, port)), 10000, 32 * 1024 * 1024); } else { gDailyLogger->error("connect failed {}:{}", ip, port); } }).detach(); } } alreadyConnectingServersLock.unlock(); }
int main() { if (readConfig()) { ox_dir_create("logs"); ox_dir_create("logs/ConnectionServer"); gDailyLogger = std::make_shared<WrapLog>(); gDailyLogger->setFile("", "logs/ConnectionServer/daily"); startServer(); std::map<string, string> etcdKV; WrapJsonValue serverJson(rapidjson::kObjectType); serverJson.AddMember("ID", gSelfID); serverJson.AddMember("IP", selfIP); serverJson.AddMember("portForClient", portForClient); serverJson.AddMember("portForLogicServer", portForLogicServer); etcdKV["value"] = serverJson.toString(); etcdKV["ttl"] = std::to_string(15); /*存活时间为15秒*/ while (true) { if (app_kbhit()) { string input; std::getline(std::cin, input); gDailyLogger->warn("console input {}", input); if (input == "quit") { break; } } for (auto& etcd : etcdServers) { if (!etcdSet(std::get<0>(etcd), std::get<1>(etcd), string("ConnectionServerList/") + std::to_string(gSelfID), etcdKV, 5000).getBody().empty()) { break; } } std::this_thread::sleep_for(std::chrono::milliseconds(5000)); /*5s 重设一次*/ } gListenClient->closeListenThread(); gListenLogic->closeListenThread(); gServer->getService()->closeListenThread(); gServer->getService()->stopWorkerThread(); gDailyLogger->stop(); } return 0; }
void ConnectionServerConnection::onClose() { gDailyLogger->warn("dis connect of connection server"); gAllLogicConnectionServerClient.erase(mConnectionServerID); if (mIsSuccess) { eraseConnectingServer(mIDInEtcd); } }
void initCenterServerExt() { /*处理来自内部服务器的rpc请求,请求者为:gCenterServerSessionRpcFromer*/ CenterServerSessionGlobalData::getCenterServerSessionRpc()->def("testrpc", [](const std::string& a, int b, dodo::RpcRequestInfo info){ gDailyLogger->info("rpc handle: {} - {}", a, b); }); /*处理来自内部服务器发送的OP消息*/ CenterServerSessionGlobalData::registerUserMsgHandle(CENTER_SERVER_EXT_RECV_OP_TEST, [](CenterServerSession&, ReadPacket& rp){ std::string a = rp.readBinary(); int b = rp.readINT32(); }); }
void ConnectionServerConnection::onEnter() { if (!isAlreadyConnecting(mIDInEtcd)) { mIsSuccess = true; addConnectingServer(mIDInEtcd, getIP(), mPort); gDailyLogger->warn("connect connection server success "); /* 发送自己的ID给连接服务器 */ TinyPacket packet(CONNECTION_SERVER_RECV_LOGICSERVER_LOGIN); packet.writeBinary(ConnectionServerPassword::getInstance().getPassword()); packet.writeINT32(gSelfID); packet.writeBool(gIsPrimary); sendPacket(packet); ping(); } }
void ConnectionServerConnection::onMsg(const char* data, size_t len) { ReadPacket rp(data, len); rp.readPacketLen(); PACKET_OP_TYPE op = rp.readOP(); switch (op) { case CONNECTION_SERVER_SEND_PONG: { } break; case CONNECTION_SERVER_SEND_LOGICSERVER_RECVCSID: { /*收到所链接的连接服务器的ID*/ mConnectionServerID = rp.readINT32(); bool isSuccess = rp.readBool(); string reason = rp.readBinary(); if (isSuccess) { gDailyLogger->info("登陆链接服务器 {} 成功", mConnectionServerID); assert(gAllLogicConnectionServerClient.find(mConnectionServerID) == gAllLogicConnectionServerClient.end()); gAllLogicConnectionServerClient[mConnectionServerID] = shared_from_this(); } else { gDailyLogger->error("登陆链接服务器 {} 失败,原因:{}", mConnectionServerID, reason); } } break; case CONNECTION_SERVER_SEND_LOGICSERVER_INIT_CLIENTMIRROR: { int64_t socketID = rp.readINT64(); int64_t runtimeID = rp.readINT64(); gDailyLogger->info("recv init client {} :{}", socketID, runtimeID); ClientMirror::PTR p = std::make_shared<ClientMirror>(runtimeID, mConnectionServerID, socketID); gClientMirrorMgr->AddClientOnRuntimeID(p, runtimeID); auto callback = ClientMirror::getClientEnterCallback(); if (callback != nullptr) { callback(p); } } break; case CONNECTION_SERVER_SEND_LOGICSERVER_DESTROY_CLIENT: { int64_t runtimeID = rp.readINT64(); gDailyLogger->info("recv destroy client, runtime id:{}", runtimeID); ClientMirror::PTR client = gClientMirrorMgr->FindClientByRuntimeID(runtimeID); gClientMirrorMgr->DelClientByRuntimeID(runtimeID); auto callback = ClientMirror::getClientDisConnectCallback(); if (callback != nullptr) { callback(client); } } break; case CONNECTION_SERVER_SEND_LOGICSERVER_FROMCLIENT: { /* 表示收到链接服转发过来的客户端消息包 */ int64_t clientRuntimeID = rp.readINT64(); const char* s = nullptr; size_t len = 0; rp.readBinary(s, len); if (s != nullptr) { ClientMirror::PTR client = gClientMirrorMgr->FindClientByRuntimeID(clientRuntimeID); if (client != nullptr) { client->procData(s, len); } } } break; default: { assert(false); } break; } }
int main() { int listenPort; /*代理服务器的监听端口*/ std::vector<std::tuple<int, string, int>> backendConfigs; { struct msvalue_s config(true); L = luaL_newstate(); luaopen_base(L); luaL_openlibs(L); /*TODO::由启动参数指定配置路径*/ lua_tinker::dofile(L, "Config.lua"); aux_readluatable_byname(L, "ProxyConfig", &config); map<string, msvalue_s*>& allconfig = *config._map; listenPort = atoi(allconfig["listenPort"]->_str.c_str()); sharding_function = allconfig["sharding_function"]->_str; map<string, msvalue_s*>& backends = *allconfig["backends"]->_map; for (auto& v : backends) { map<string, msvalue_s*>& oneBackend = *(v.second)->_map; int id = atoi(oneBackend["id"]->_str.c_str()); string dbServerIP = oneBackend["ip"]->_str; int port = atoi(oneBackend["port"]->_str.c_str()); backendConfigs.push_back(std::make_tuple(id, dbServerIP, port)); } } gDailyLogger = std::make_shared<WrapLog>(); spdlog::set_level(spdlog::level::info); ox_dir_create("logs"); ox_dir_create("logs/DBProxyServer"); gDailyLogger->setFile("", "logs/DBProxyServer/daily"); EventLoop mainLoop; WrapServer::PTR server = std::make_shared<WrapServer>(); /*开启网络线程*/ server->startWorkThread(1, [&](EventLoop&){ syncNet2LogicMsgList(mainLoop); }); /*链接数据库服务器*/ for (auto& v : backendConfigs) { int id = std::get<0>(v); string ip = std::get<1>(v); int port = std::get<2>(v); gDailyLogger->info("connec db server id:{}, address: {}:{}", id, ip, port); sock fd = ox_socket_connect(ip.c_str(), port); auto bserver = std::make_shared<BackendLogicSession>(); bserver->setID(id); WrapAddNetSession(server, fd, make_shared<BackendExtNetSession>(bserver), -1); } gDailyLogger->info("listen proxy port:{}", listenPort); /*开启代理服务器监听*/ server->getListenThread().startListen(listenPort, nullptr, nullptr, [&](int fd){ WrapAddNetSession(server, fd, make_shared<ClientExtNetSession>(std::make_shared<ClientLogicSession>()), -1); }); gDailyLogger->warn("db proxy server start!"); while (true) { mainLoop.loop(1); /* 处理网络线程投递过来的消息 */ procNet2LogicMsgList(); } std::cin.get(); lua_close(L); L = nullptr; return 0; }