示例#1
0
void KristalliProtocolModule::Update(f64 frametime)
{
    // Update method for multiconnection.
    if (!serverConnection_map_.isEmpty())
        connectionArrayUpdate();


    // Pulls all new inbound network messages and calls the message handler we've registered
    // for each of them.
    if (serverConnection)
        serverConnection->Process();


    // Note: Calling the above serverConnection->Process() may set serverConnection to null if the connection gets disconnected.
    // Therefore, in the code below, we cannot assume serverConnection is non-null, and must check it again.

    // Our client->server connection is never kept half-open.
    // That is, at the moment the server write-closes the connection, we also write-close the connection.
    // Check here if the server has write-closed, and also write-close our end if so.
    if (serverConnection && !serverConnection->IsReadOpen() && serverConnection->IsWriteOpen())
        serverConnection->Disconnect(0);


    // Process server incoming connections & messages if server up
    if (server)
    {
        server->Process();

        // In Tundra, we *never* keep half-open server->client connections alive.
        // (the usual case would be to wait for a file transfer to complete, but Tundra messaging mechanism doesn't use that).
        // So, bidirectionally close all half-open connections.
        NetworkServer::ConnectionMap connections = server->GetConnections();
        for(NetworkServer::ConnectionMap::iterator iter = connections.begin(); iter != connections.end(); ++iter)
            if (!iter->second->IsReadOpen() && iter->second->IsWriteOpen())
                iter->second->Disconnect(0);
    }

    if ((!serverConnection || serverConnection->GetConnectionState() == ConnectionClosed ||
            serverConnection->GetConnectionState() == ConnectionPending) && serverIp.length() != 0)
    {
        const int cReconnectTimeout = 5 * 1000.f;
        if (reconnectTimer.Test())
        {
            if (reconnectAttempts)
            {
                PerformConnection();
                --reconnectAttempts;
            }
            else
            {
                LogInfo("Failed to connect to " + serverIp + ":" + ToString(serverPort));
                // If connection fails we just ignore it. Client has no use for information if initial connection failed.
                //framework_->GetEventManager()->SendEvent(networkEventCategory, Events::CONNECTION_FAILED, 0);
                reconnectTimer.Stop();
                serverIp = "";
            }
        }
        else if (!reconnectTimer.Enabled())
            reconnectTimer.StartMSecs(cReconnectTimeout);
    }

    // If connection was made, enable a larger number of reconnection attempts in case it gets lost
    if (serverConnection && serverConnection->GetConnectionState() == ConnectionOK)
    {
        // save succesfully established connection to messageconnection array with all connection properties.
        for (unsigned short connection = 0;; connection++)
        {
            if (!serverConnection_map_.contains(connection))
            {
                // Associative QMap stores all items sorted by Key. If array has one item terminated,
                // we fill it with next succesfull connection. Same is done in client.
                serverConnection_map_.insert(connection, serverConnection);
                serverIp_list_.insert(connection,serverIp);
                serverPort_list_.insert(connection,serverPort);
                serverTransport_list_.insert(connection, serverTransport);
                reconnectAttempts_list_.insert(connection, cReconnectAttempts);
                reconnectTimer.Reset();
                reconnectTimer_list_.insert(connection,reconnectTimer);

                serverConnection = 0;
                serverIp = "";
                serverPort = 0;

                break;
            }
        }
    }


    RESETPROFILER;
}
示例#2
0
void KristalliProtocolModule::Update(f64 /*frametime*/)
{
    // Pulls all new inbound network messages and calls the message handler we've registered
    // for each of them.
    if (serverConnection)
    {
        PROFILE(KristalliProtocolModule_kNet_client_Process);
        serverConnection->Process();
    }

    // Note: Calling the above serverConnection->Process() may set serverConnection to null if the connection gets disconnected.
    // Therefore, in the code below, we cannot assume serverConnection is non-null, and must check it again.

    // Our client->server connection is never kept half-open.
    // That is, at the moment the server write-closes the connection, we also write-close the connection.
    // Check here if the server has write-closed, and also write-close our end if so.
    if (serverConnection && !serverConnection->IsReadOpen() && serverConnection->IsWriteOpen())
        serverConnection->Disconnect(0);
    
    // Process server incoming connections & messages if server up
    if (server)
    {
        PROFILE(KristalliProtocolModule_kNet_server_Process);

        server->Process();

        // In Tundra, we *never* keep half-open server->client connections alive. 
        // (the usual case would be to wait for a file transfer to complete, but Tundra messaging mechanism doesn't use that).
        // So, bidirectionally close all half-open connections.
        NetworkServer::ConnectionMap connections = server->GetConnections();
        for(NetworkServer::ConnectionMap::iterator iter = connections.begin(); iter != connections.end(); ++iter)
            if (!iter->second->IsReadOpen() && iter->second->IsWriteOpen())
                iter->second->Disconnect(0);
    }
    
    if ((!serverConnection || serverConnection->GetConnectionState() == ConnectionClosed ||
        serverConnection->GetConnectionState() == ConnectionPending) && serverIp.length() != 0)
    {
        const int cReconnectTimeout = 5 * 1000.f;
        if (reconnectTimer.Test())
        {
            if (reconnectAttempts)
            {
                PerformConnection();
                --reconnectAttempts;
            }
            else
            {
                ::LogInfo(QString("Failed to connect to %1:%2").arg(serverIp.c_str()).arg(serverPort));
                emit ConnectionAttemptFailed();

                reconnectTimer.Stop();
                serverIp = "";
            }
        }
        else if (!reconnectTimer.Enabled())
            reconnectTimer.StartMSecs(cReconnectTimeout);
    }

    // If connection was made, enable a larger number of reconnection attempts in case it gets lost
    if (serverConnection && serverConnection->GetConnectionState() == ConnectionOK)
        reconnectAttempts = cReconnectAttempts;
}