8 votes

Quelle est la bonne façon de faire des appels ajax continus ?

J'ai un code comme celui-ci pour mettre à jour un graphique sur ma page en temps réel toutes les 30 secondes :

var counter = 30;

$(function() {
    prepare();
    update();
});

function update() {
    $("#timer").html("Refreshing in " + counter + " seconds...");
    counter--;

    if (counter == 0) {
        counter = 30;
        prepare();
    }

    setTimeout(update, 1000);
}

function prepare() {
    $.ajax({
        type: "POST",
        url: "Service.asmx/GetPlotData",
        contentType: "application/json; charset=utf-8",
        success: OnSuccess, // this function plots the new data
        error: OnError
    });
}

Cela semble fonctionner correctement, mais après 16 à 20 heures d'appels ajax continus, je reçois une erreur du serveur :

Le délai d'attente a expiré. Le délai d'attente s'est écoulé avant l'obtention d'une réponse de l'entreprise. connexion depuis le pool. Cela peut s'être produit parce que toutes les étaient utilisées et la taille maximale du pool était atteinte.

J'ai lancé la console de débogage et voici ce que j'observe :

Les appels AJAX sont lancés correctement

enter image description here

Avant la période de 16 à 20 heures, il y a quelques cas où la latence augmente (c'est là que l'on peut voir l'augmentation de la latence). Timeout l'erreur est vue pour la première fois)

enter image description here

Finalement, le code arrive à rencontrer un goulot d'étranglement. La latence augmente pour chaque appel et le front-end se casse. Aucun appel après la flèche bleue ci-dessous ne renvoie de données. Au lieu de cela, il jette l'erreur de timeout.

enter image description here

Je suis sûr que je fais quelque chose de fondamentalement mauvais. Avez-vous des idées sur la façon de résoudre ce problème ?

EDIT : Code côté serveur

Ma chaîne de connexion :

Data Source={0};Initial Catalog={1};Integrated Security=True;MultipleActiveResultSets=true

Le code pour extraire les enregistrements :

try
{
    string ConString = Constants.connString;
    con = new SqlConnection(ConString);

    cmd = new SqlCommand(sql, con);
    con.Open();
    dr = cmd.ExecuteReader();

    while (dr.Read())
    {
        // Add the records into an object
    }

}
catch (Exception x)
{
     // Send back some error text.
     // This is what is giving out the Timeout error
}
finally
{
    con.Close();
}

À moins que quelque chose ne m'échappe, je ferme la connexion après avoir obtenu les enregistrements à l'aide de la fonction con.Close() ou y a-t-il autre chose que je doive faire ?

EDIT 2 : Je modifie le code ci-dessus comme suit. Est-ce correct ?

try
{
    string ConString = Constants.connString;

    using (con = new SqlConnection(ConString))
    {
        cmd = new SqlCommand(sql, con);
        con.Open();
        dr = cmd.ExecuteReader();

        while (dr.Read())
        {
            // Add rows to object
        }
    }

}
catch (Exception x)
{
    // Handle error
}
finally
{
    con.Close();
}

4voto

Juan Pablo Santos Points 56

Cela ressemble à un problème côté serveur avec trop de connexions à une base de données. Comment vous connectez-vous à la base de données ? Fermez-vous la connexion après l'avoir utilisée ? Essayez de fermer la connexion après un certain nombre de connexions.

1voto

Cory Kendall Points 3403

"Je reçois une erreur en retour du serveur" me fait penser à une fuite de ressources côté serveur. Que se passe-t-il si vous exécutez deux onglets de navigateur en parallèle, ou deux navigateurs en parallèle, ou deux hôtes avec leurs propres navigateurs frappant le serveur en parallèle ?

La mémoire de votre navigateur augmente-t-elle avec le temps ?

Si vous avez accès aux journaux du côté du serveur, ce serait également un point à approfondir.

EDIT

Après avoir vu le code du serveur, vous voudrez peut-être aussi fermer le lecteur par sécurité ; je serais surpris que cela provoque une fuite, mais on ne sait jamais. Je suis plus familier avec Java, où cela peut provoquer une fuite en fonction du pilote sous-jacent utilisé.

dr.Close();
con.Close();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X