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;
    }
}
Beispiel #7
0
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;
}