2008-08-30 9 views
13

En el proyecto en el que estoy trabajando actualmente, tenemos la necesidad de desarrollar una aplicación de chat web, no un chat muy complejo, solo una forma de conectar a dos personas para hablar sobre un tema muy específico, no Necesitamos cualquier tipo de autenticación para uno de los dos usuarios, no tenemos que admitir emoticones, avatares o cosas por el estilo.Ajax polling

Algunos miembros del proyecto sugirieron que podríamos usar XMPP a través de BOSH, dije que era como tratar de atrapar un pez con la red de un bote, y propuse un método más simple, como un simple chat web Ajax/MySQL, pero Estamos preocupados por el rendimiento alcanzado en el servidor debido a la votación constante de muchos chats abiertos al mismo tiempo.

¿Alguien ha hecho algo así antes? ¿Qué recomendarías?

Respuesta

6

Es posible que también desee consultar Comet.

Es utilizado por GTalk, Meebo y muchos other chat applications. Hace unos años, cuando estaba experimentando con él, no había muchas bibliotecas o detalles sobre la arquitectura de servidor para implementarlo, pero parece que ahora hay muchas más cosas. Para obtener más información técnica, consulte el proyecto cometd.

5

¿Qué recomendarías?

XMPP a través BOSH

No hay necesidad de inventar su propio formato de mensaje y protocolo de transporte cuando alguien más tiene. Si lo intenta, poco a poco crecerá para ser tan complejo como BOSH, pero sin el beneficio de la compatibilidad con la biblioteca de terceros o la estandarización.

0

Pensé que todos usaban comed para este tipo de cosas.

2

Es posible que también desee buscar en Comet.

Pensé que todos usaban comed para este tipo de cosas.

BOSH es un estándar para transportar XMPP a través de HTTP. Implica a Comet para enviar datos al cliente.

1

Hice esta misma cosa hace unos meses y me divertí jugando con los conceptos. De hecho, utilicé la técnica forever-frame en lugar de sondear.

El siguiente código es mi archivo js "cometa" que contiene los conceptos generales necesarios para obtener una configuración de "chat de fiesta".

function Comet(key) { 

    var random = key; 
    var title = 'Comet'; 
    var connection = false; 
    var iframediv = false; 
    var browserIsIE = /*@[email protected]*/false; 
    var blurStatus = false; 
    var tmpframe = document.createElement('iframe'); 
    var nl = '\r\n'; 

    this.initialize = function() { 
    if (browserIsIE) { 
     connection = new ActiveXObject("htmlfile"); 
     connection.open(); 
     connection.write("<html>"); 
     connection.write("<script>document.domain = '"+document.domain+"'"); 
     connection.write("</html>"); 
     connection.close(); 
     iframediv = connection.createElement("div"); 
     connection.appendChild(iframediv); 
     connection.parentWindow.comet = comet; 
     iframediv.innerHTML = "<iframe id='comet_iframe' src='./comet.aspx?key="+random+"'></iframe>"; 
    } else { 
     connection = document.createElement('iframe'); 
     connection.setAttribute('id', 'comet_iframe'); 
     iframediv = document.createElement('iframe'); 
     iframediv.setAttribute('src', './comet.aspx?key='+random); 
     connection.appendChild(iframediv); 
     document.body.appendChild(connection); 
    } 
    } 

    // this function is called from the server to keep the connection alive 
    this.keepAlive = function() { 
    if (!browserIsIE) { 
     mozillaHack(); 
    } 
    } 

    // this function is called from the server to update the client 
    this.updateClient = function (value) { 
    var outputDiv = document.getElementById('output'); 
    outputDiv.value = value + nl + outputDiv.value; 
    if (blurStatus == true) { 
     document.title = value; 
    } 
    if (!browserIsIE) { 
     mozillaHack(); 
    } 
    } 

    this.onUnload = function() { 
    if (connection) { 
     // this will release the iframe to prevent problems with IE when reloading the page 
     connection = false; 
    } 
    } 

    this.toggleBlurStatus = function(bool) { 
    blurStatus = bool; 
    } 

    this.resetTitle = function() { 
    document.title = title; 
    } 

    function mozillaHack() { 
    // this hack will fix the hour glass and loading status for Mozilla browsers 
    document.body.appendChild(tmpframe); 
    document.body.removeChild(tmpframe); 
    } 
} 
+0

se esta técnica rquired tener Tomcat en tercera cometa en .etc biblioteca? o se puede servir en un servlet típico? ¿Hay alguna aplicación de demostración/trabajo a la que podamos hacer referencia? – cometta

+0

puede mostrarnos un ejemplo de comet.aspx? – cometta

+0

Esta técnica no requiere nada más allá de IIS6 y .NET para comenzar a funcionar. –

0

Estoy de acuerdo con John. Pero había otra pregunta que no fue respondida.
He hecho esto, pero en lugar de usar una base de datos usamos un archivo plano, pero finalmente bloqueó el servidor, pero no fue hasta que tenemos ~ 450 usuarios activos, y si lo hubiéramos hecho con una base de datos, probablemente lo haría han ido mejor.
Esto se hizo en una cuenta de hosting básica de Godaddy.

Edit: BTW Godaddy sonaba menos que divertido cuando recibí la llamada telefónica.

2

hay un muy buen servidor para la gestión de mensajes empujando desde el servidor al navegador (apodado Comet) - Orbited. Se integra fácilmente con otras tecnologías (Django, Rails, PHP, etc.) al igual que memcached.

Realmente debería comprobar si desea manejar una carga grave. De lo contrario, la encuesta simple de Ajax es la mejor manera.

1

El truco consiste en darse cuenta de que la única vez que su aplicación necesita invocar CGI en el servidor es cuando alguien dice algo. Para las encuestas regulares, consulte una página estática que su secuencia de comandos CGI actualiza cada vez que hay un nuevo chat. Use las solicitudes HEAD, compare las marcas de tiempo con las vistas por última vez, y solo haga un GET completo cuando cambien. Tengo una aplicación de chat sencilla e ingenua implementada de esta manera, y el uso de carga y ancho de banda es insignificante para las pocas decenas de usuarios simultáneos que tenemos.

3

Si no le gusta la idea de la encuesta HTTP, podría tener una película Flash en la página de chat que tenga una conexión constante con algún deamon en el servidor, la película Flash invocaría funciones de JavaScript en el cliente para actualizar el chat a medida que aparecen nuevos mensajes. (A menos que desee una interfaz Flash para su chat ...)

0

Acabo de encontrar esta publicación, es antigua, pero el concepto de encuesta da problemas a mucha gente. Así que pondré un ejemplo de implementación aquí. Pero antes de dárselos, debería darle un consejo que me hizo enojar hace tiempo:

Cuando realice una encuesta, debe encargarse del comportamiento de las sesiones (race conditions). Para simplificar: si abre una sesión, el archivo de sesión se bloquea hasta que la sesión se cierre para evitar que 2 personas escriban datos diferentes en ella. Por lo tanto, si necesita una sesión para verificar si un usuario está conectado o no, siempre cierre la sesión antes del sondeo.

Mi demostración le da un ejemplo de una implementación de sondeo en PHP. No usaré una base de datos, sino un archivo. Cuando haga clic en el botón de sondeo, ingresará el ciclo y hasta que se modifique el archivo, se mantendrá el sondeo. Cuando rellene el formulario y haga clic en Liberar, lo que escribió se guardará en el archivo. El tiempo de modificación del archivo cambiará, por lo que el sondeo se detendrá.

Consejo: use una herramienta como Firebug para ver qué pasa.

Ahora vamos a hablar en una mejor langage que mi Inglés:

<?php 

    // For this demo 
    if (file_exists('poll.txt') == false) { 
     file_put_contents('poll.txt', ''); 
    } 

    if (isset($_GET['poll'])) { 

     // Don't forget to change the default time limit 
     set_time_limit(120); 

     date_default_timezone_set('Europe/Paris'); 
     $time = time(); 

     // We loop until you click on the "release" button... 
     $poll = true; 
     $number_of_tries = 1; 
     while ($poll) 
     { 
      // Here we simulate a request (last mtime of file could be a creation/update_date field on a base) 
      clearstatcache(); 
      $mtime = filemtime('poll.txt'); 

      if ($mtime > $time) { 
       $result = htmlentities(file_get_contents('poll.txt')); 
       $poll = false; 
      } 

      // Of course, else your polling will kill your resources! 
      $number_of_tries++; 
      sleep(1); 
     } 

     // Outputs result 
     echo "Number of tries : {$number_of_tries}<br/>{$result}"; 
     die(); 
    } 

    // Here we catch the release form 
    if (isset($_GET['release'])) 
    { 
     $data = ''; 
     if (isset($_GET['data'])) { 
      $data = $_GET['data']; 
     } 
     file_put_contents('poll.txt', $data); 
     die(); 
    } 

?> 

<!-- click this button to begin long-polling --> 
<input id="poll" type="button" value="Click me to start polling" /> 

<br/><br/> 

Give me some text here : 
<br/> 
<input id="data" type="text" /> 
<br/> 

<!-- click this button to release long-polling --> 
<input id="release" type="button" value="Click me to release polling" disabled="disabled" /> 

<br/><br/> 

Result after releasing polling : 
<div id="result"></div> 

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> 
<script type="text/javascript"> 

// Script to launch polling 
$('#poll').click(function() { 
    $('#poll').attr('disabled', 'disabled'); 
    $('#release').removeAttr('disabled'); 
    $.ajax({ 
     url: 'poll.php', 
     data: { 
      poll: 'yes' // sets our $_GET['poll'] 
     }, 
     success: function(data) { 
      $('#result').html(data); 
      $('#poll').removeAttr('disabled'); 
      $('#release').attr('disabled', 'disabled'); 
     } 
    }); 
}); 

// Script to release polling 
$('#release').click(function() { 
    $.ajax({ 
     url: 'poll.php', 
     data: { 
      release: 'yes', // sets our $_GET['release'] 
      data: $('#data').val() // sets our $_GET['data'] 
     } 
    }); 
}); 

</script> 

se puede probar here

Cuestiones relacionadas