2009-07-10 9 views
14

Page Web de demande client du serveur. Clent demande ensuite que des calculs supplémentaires soient effectués; le serveur effectue une série de calculs et envoie des résultats partiels dès qu'ils sont disponibles (format texte, chaque ligne contient un élément complet distinct). Le client met à jour la page Web (avec JavaScript et DOM) en utilisant les informations fournies par le serveur.Implémentation multi-navigateurs du modèle "HTTP Streaming" (push) AJAX

Cela semble correspondre à HTTP Streaming (current version) motif à partir du site Ajaxpatterns.

La question est de savoir comment le faire de façon croisée (navigateur agnostique), de préférence sans utiliser de frameworks JavaScript, ou en utilisant un framework léger comme jQuery. Le problème commence par la génération de XMLHttpRequest de manière croisée, mais je pense que l'élément principal est que tous les navigateurs ne sont pas implémentés correctement onreadystatechange de XMLHttpRequest; Tous les navigateurs appellent onreadystatechange événement sur chaque vidage de serveur (BTW .. comment forcer le vidage du serveur à partir du script CGI (en Perl)?). Exemple de code sur Ajaxpatterns traite cela en utilisant timer; devrais-je laisser tomber la solution de minuterie si je détecte une réponse partielle de onreadystatechange?


Ajouté 11-08-2009

solution actuelle:
utiliser la fonction suivante pour créer l'objet XMLHttpRequest:

function createRequestObject() { 
     var ro; 
     if (window.XMLHttpRequest) { 
       ro = new XMLHttpRequest(); 
     } else { 
       ro = new ActiveXObject("Microsoft.XMLHTTP"); 
     } 
     if (!ro) 
       debug("Couldn't start XMLHttpRequest object"); 
     return ro; 
} 

Si je devais utiliser certains (de préférence légers) cadre JavaScript comme jQuery, je voudrais avoir de secours si l'utilisateur choisit de ne pas installer jQuery. J'utilise le code suivant pour démarrer AJAX; setInterval est utilisé parce que certains navigateurs appellent onreadystatechange seulement après que le serveur ferme la connexion (ce qui peut prendre des dizaines de secondes), et non dès que le serveur vide les données (environ toutes les secondes ou plus souvent).

function startProcess(dataUrl) { 
     http = createRequestObject(); 
     http.open('get', dataUrl); 
     http.onreadystatechange = handleResponse; 
     http.send(null); 

     pollTimer = setInterval(handleResponse, 1000); 
} 

La fonction handleResponse est plus compliquée, mais l'esquisse de celui-ci se présente comme suit. Cela peut-il être mieux fait? Comment cela se ferait-il en utilisant un framework JavaScript léger (comme jQuery)?

function handleResponse() { 
    if (http.readyState != 4 && http.readyState != 3) 
     return; 
    if (http.readyState == 3 && http.status != 200) 
     return; 
    if (http.readyState == 4 && http.status != 200) { 
     clearInterval(pollTimer); 
     inProgress = false; 
    } 
    // In konqueror http.responseText is sometimes null here... 
    if (http.responseText === null) 
     return; 

    while (prevDataLength != http.responseText.length) { 
     if (http.readyState == 4 && prevDataLength == http.responseText.length) 
      break; 
     prevDataLength = http.responseText.length; 
     var response = http.responseText.substring(nextLine); 
     var lines = response.split('\n'); 
     nextLine = nextLine + response.lastIndexOf('\n') + 1; 
     if (response[response.length-1] != '\n') 
      lines.pop(); 

     for (var i = 0; i < lines.length; i++) { 
      // ... 
     } 
    } 

    if (http.readyState == 4 && prevDataLength == http.responseText.length) 
     clearInterval(pollTimer); 

    inProgress = false; 
} 
+0

Vous devriez certainement ajouter cet exemple de code comme réponse et le marquer comme le bon! –

+4

"si l'utilisateur choisit de ne pas installer jQuery"? – Basic

+0

Salut, je suis juste tombé sur votre solution, mais je crains que cela ne fonctionne toujours pas avec IE, puisque lorsque vous essayez d'obtenir le responseText alors que les demandes ne sont pas encore terminées, alors vous obtiendrez ce qui suit message: "Les données nécessaires pour compléter cette opération ne sont pas encore disponibles". –

Répondre

2

La solution à laquelle vous avez lié n'est en aucun cas AJAX. Ils l'appellent HTTP Streaming mais c'est essentiellement un long sondage.

Dans l'exemple auquel ils sont liés, vous pouvez facilement voir par vous-même avec firebug. Allumez le panneau net - il n'y a pas d'entrées XHR, mais il suffit d'un cheveu de plus de 10 secondes pour charger la page d'origine. C'est parce qu'ils utilisent PHP dans les coulisses pour retarder la sortie du HTML. C'est l'essence de l'interrogation longue - la connexion HTTP reste ouverte, et le code HTML périodique renvoyé est des commandes javascript.

Vous pouvez choisir de faire le vote complètement sur le côté client, cependant, avec setTimeout() ou setInterval()

Un exemple jQuery

<script type="text/javascript"> 
    $(document).ready(function() 
    { 
    var ajaxInterval = setInterval(function() 
    { 
     $.getJSON(
     'some/servie/url.ext' 
     , { sample: "data" } 
     , function(response) 
      { 
      $('#output').append(response.whatever);   
      } 
    ); 
    }, 10000); 
    }); 
</script> 
+0

Pas exactement ce que je veux. Le calcul sur le serveur génère une sortie au format texte brut. Avec XHR je peux obtenir cette réponse directement dans le client (onreadystatechange sur flush/timer) et éditer la page Web en fonction des données partielles que je reçois. –

+0

Qu'est-ce que vous ne voulez pas? Le long sondage? Je ne recommande pas l'une ou l'autre méthode - je vous dis seulement quelles sont vos options. –

+0

Si vous souhaitez utiliser un pool long (Comet), vous devriez envisager d'utiliser le logiciel serveur Meteor, car Apache n'est pas conçu pour ce genre de choses. Et il y a aussi une librairie javascript qui gère presque tout pour vous, je ne me souviens plus de son nom, je l'afficherai plus tard. – usoban

0

Je prendrais un coup d'œil à désorbité

Ils utilisent plusieurs implémentations de transport de comètes qu'ils ont choisies en fonction de la configuration et du reniflage du navigateur.

Voir http://orbited.org/svn/orbited/trunk/daemon/orbited/static/Orbited.js

et recherchez « Orbited.CometTransports »

Certains des différents moyens de transport doivent aller de pair la mise en œuvre de back-end, afin de jeter un oeil sur le côté serveur pour également mis en orbite.

Questions connexes