2011-03-10 21 views
7

Esta es una pregunta muy compleja y de nicho, por lo que puede que no haya una respuesta realista para lo que tengo que hacer.¿Cómo hacer sockets en jQuery?

Tengo una asignación para trabajar con un receptor inalámbrico, que necesita más que la funcionalidad get/post de jQuery.

Debido a problemas de dominio cruzado, este jQuery get se ejecuta dentro de una aplicación de Adobe Air, creada en Aptana IDE.

Tiene que ser un adobe air, porque el servidor web no estará cerca de donde el receptor inalámbrico eventualmente estará conectado.

Necesito una aplicación que pueda comunicarse con el receptor inalámbrico 2Know Renaissance.

He creado una aplicación que funciona bien con algunas de las comunicaciones. Aquí están los pasos que puedo hacer hasta ahora.

  1. conectarse al receptor
  2. ver cuántos dispositivos de mano se conecta al receptor
  3. Luego se supone que es un poco de avance/retroceso de comunicación, y eso no es fácil con en Ajax al menos en mi conocimiento .

Aquí está el código con el que he estado trabajando, esta es la versión número 24, y esto es todo lo que he conseguido.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>2Know Wireless Communicator</title> 
</head> 
<body> 
<h1>Current Status/Prograess</h1> 

<!--- step 1. is server connected ---> 
<div id="server_status" style="font-size:12px;"></div> 

<!--- step 2. list number of devices connected ---> 
<div id="device_count" style="font-size:12px;"></div> 
<div id="device_info" style="font-size:12px;"></div> 

<!--- step 3.a Service Handler handler status/csh = Service Handler handler ---> 
<div id="csh_status" style="font-size:12px;"></div> 

<!--- step 3.b disconnect status handler handler of many handlers ---> 
<div id="dis_status" style="font-size:12px;"></div> 

<!--- step 4. test sending a question to a device ---> 
<div id="post_results" style="font-size:12px;"></div> 

<!-- load the local jquery --> 
<script type="text/javascript" src="lib/jquery/jquery-1.4.2.js"></script> 
<script type="text/javascript" src="lib/jquery/json_parse.js"></script> 
<script type="text/javascript" src="lib/jquery/jparse.min.js"></script> 
<script type="text/javascript" src="lib/air/AIRAliases.js"></script> 
<script type="text/javascript" src="lib/air/AIRIntrospector.js" /> 
<!-- Include service monitor framework --> 
<script type="application/x-shockwave-flash" src="lib/air/servicemonitor.swf"></script> 


<script type="text/javascript"> 
function watch_connection() { 
    // do ajax get 
    $.ajax({ 
     type: "GET", 
     datatype: "xml", 
     url: "http://my_ip_address:port/Services/ConnectServiceHandler", 
     success: function(response){ 
      $('#post_results').html(response); 
     }, 
     error:function (xhr, ajaxOptions, thrownError){ 
      $('#post_results').html("readyState: "+xhr.readyState+"\nstatus: "+xhr.status); 
     } 
    }); 
    setTimeout(function(){watch_connection;}, 100); 
} 

function disconnect_service_handler() { 

    // step 1. create xml document of data to send 
    var xml_string = '<data><disconnect_handler service="64"/></data>'; 

    // step 2. post this to the registration service 
    $.ajax({ 
     type: "POST", 
     datatype: "xml", 
     url:"http://my_ip_address:port/Services/DisconnectServiceHandler", 
     data: xml_string, 
     beforeSend: function(xhr){ 
       xhr.withCredentials = true; 
     }, 
     timeout: (2 * 1000), 
     success: function(response){ 

      // parse the response 
      $(response).find("status").each(function() { 
       // get the status code 
       var disconnect_status = $(this).attr('code'); 

       if (disconnect_status == 200) { 
        // change status bar message 
        $('#dis_status').html('Disconnecting: [200 Disconnected]'); 

        // call connection using new guid 
        var my_guid = guid(); 
        connect_service_handler(my_guid); 
       } 

       if (disconnect_status == 304) { 
        // change status bar message 
        $('#dis_status').html('Disconnecting: [304 No handler found]'); 
       } 


       if (disconnect_status == 400) { 
        // change status bar message 
        $('#dis_status').html('Disconnecting: [400 Bad Request]'); 
       } 

       if (disconnect_status == 401) { 
        // change status bar message 
        $('#dis_status').html('Disconnecting: [401 Not Found]'); 
       } 

       if (disconnect_status == 500) { 
        // change status bar message 
        $('#dis_status').html('Disconnecting: [500 Internal Server Failure]'); 
       } 

       if (disconnect_status == 501) { 
        // change status bar message 
        $('#dis_status').html('Disconnecting: [503 Service Unavailable]'); 
       } 


      }); 


     }, 
     error:function (xhr, ajaxOptions, thrownError){ 
      $('#dis_status').html('Disconnecting: [Disconnect Failure]'); 
     } 

    }); 
} 
function S4() { 
    return (((1+Math.random())*0x10000)|0).toString(16).substring(1); 
} 
function guid() { 
    return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4()); 
} 
function connect_service_handler(my_guid) { 

    // step 1. create xml document of data to send 
    var xml_string = '<data><connect_handler service="64"><application id="'+my_guid+'" name="MikesBigEar" /></connect_handler></data>'; 

    // step 2. post this to the registration service 
    $.ajax({ 
     type: "POST", 
     datatype: "xml", 
     url:"http://my_ip_address:port/Services/ConnectServiceHandler", 
     data: xml_string, 
     beforeSend: function(xhr){ 
       xhr.withCredentials = true; 
     }, 
     timeout: (2 * 1000), 
     success: function(response){ 

      // parse the response 
      $(response).find("status").each(function() { 

       // get the status code 
       var connection_status = $(this).attr('code'); 

       if (connection_status == 200) { 
        // change status bar message 
        $('#csh_status').html('Service Handler: [200 Connected]'); 
        // keep connection open keep socket alive 
        // sends http request to us via post 
        // sends the incoming request id and device address back to make sure it goes to the correct device 
        // ask for user id or user authentication 
        // for user authentication can either use built-in user authentication or ask a question 
        // http 1.1 keep alive header 
        $('#post_results').html('Attempting to check for next piece of data...'); 
        watch_connection(); 
       } 

       if (connection_status == 303) { 
        // change status bar message 
        $('#csh_status').html('Service Handler: [303 The handler is assigned to another application]'); 
        var my_guid = guid(); 
        connect_service_handler(my_guid); 
       } 

       if (connection_status == 400) { 
        // change status bar message 
        $('#csh_status').html('Service Handler: [400 Bad Request]'); 
        disconnect_service_handler(); 
       } 

       if (connection_status == 401) { 
        // change status bar message 
        $('#csh_status').html('Service Handler: [401 Not Found]'); 
        disconnect_service_handler(); 
       } 

       if (connection_status == 500) { 
        // change status bar message 
        $('#csh_status').html('Service Handler: [500 Internal Server Failure]'); 
        disconnect_service_handler(); 
       } 

       if (connection_status == 501) { 
        // change status bar message 
        $('#csh_status').html('Service Handler: [501 Service Unavailable]'); 
        disconnect_service_handler(); 
       } 


      }); 

      // pass the xml to the textarea 
      // $('#process').val('ConnectServiceHandler'); 
      // $('#show_errors_here').val(response); 

     }, 
     error:function (xhr, ajaxOptions, thrownError){ 
      $('#csh_status').html('Service Handler: [Connection Failure]'); 
      // alert("readyState: "+xhr.readyState+"\nstatus: "+xhr.status); 
      // alert("responseText: "+xhr.responseText); 
      // alert(xhr.status); 
      // alert(thrownError); 
     } 

    }); 

    // set timed re-check and store it 
    // setTimeout(function(){connect_service_handler(my_guid);}, 8000); 


} 

function get_device_count(my_guid) { 
    // get the total number of devices 

    // default receiver status 
    var receiver_status = ''; 


    $('#device_count').html('Device Count: [Checking...]'); 
    $('#device_info').html(''); 

    // get the wireless receiver status via ajax xml 
    $.ajax({ 
     type: "GET", 
     url:"http://my_ip_address:port/Services/GetDevices", 
     beforeSend: function(xhr){ 
       xhr.withCredentials = true; 
     }, 
     timeout: (2 * 1000), 
     success: function(response){ 

      $(response).find("status").each(function() { 
       // get the status code 
       var receiver_status = $(this).attr('code'); 

       if (receiver_status == 200) { 
        // change status bar message 
        $('#device_count').html('Device Count: [200 Connected]'); 
       } 

       if (receiver_status == 400) { 
        // change status bar message 
        $('#device_count').html('Device Count: [400 Bad Request]'); 
       } 

       if (receiver_status == 401) { 
        // change status bar message 
        $('#device_count').html('Device Count: [401 Not Found]'); 
       } 

       if (receiver_status == 500) { 
        // change status bar message 
        $('#device_count').html('Device Count: [500 Internal Server Failure]'); 
       } 

       if (receiver_status == 501) { 
        // change status bar message 
        $('#device_count').html('Device Count: [501 Service Unavailable]'); 
       } 


      }); 

      var device_count = 0; 

      // add to div 
      $('#device_info').append('<ul style="font-size:10px;">'); 

      $(response).find("device").each(function() { 

       // get each property 
       var device_status = $(this).attr('status'); 
       var short_address = $(this).attr('short_address'); 
       var mac_address = $(this).attr('mac_address'); 
       var pan_id = $(this).attr('pan_id'); 
       var type = $(this).attr('type'); 

       device_count = device_count + 1; 

       // get session data 
       $(this).find("session").each(function() { 

        // get session data 
        var created_date = $(this).attr('date'); 
        var created_time = $(this).attr('time'); 

       }); 

       $('#device_info').append('<li style="list-style:none;">Device #'+device_count+'<ul>'); 

       // add list item 
       $('#device_info').append('<li> Mac Address: ['+mac_address+']</li>'); 
       $('#device_info').append('<li> Short Address: ['+short_address+']</li>'); 
       $('#device_info').append('<li> Pan ID: ['+pan_id+']</li>'); 

       $('#device_info').append('</ul></li><br/>'); 

       // send request to this device 
       // post_live_activity(mac_address,my_guid); 



      }); 

      // end list 
      $('#device_info').append('</ul>'); 

      if (device_count === 0) { 
       $('#device_count').html('Device Count: [0 Devices Found]'); 
      } else if (device_count > 0) { 
       $('#device_count').html('Device Count: [' + device_count + ' Devices Found]'); 
      } 


     }, 
     error:function (xhr, ajaxOptions, thrownError){ 
      $('#device_count').html('Device Count: [Connection Failure]'); 
      // alert(xhr.status); 
      // alert(thrownError); 
     } 
    }); 

    // set timed re-check and store it 
    setTimeout(function(){get_device_count(my_guid);}, 13000); 
} 
function get_server_status(my_guid) { 

    // default receiver status 
    var receiver_status = ''; 

    // get the Renaissance Wireless Server via ajax xml 
    $.ajax({ 
     type: "GET", 
     url:"http://my_ip_address:port/Services/GetAccessPoints", 
     timeout: (2 * 1000), 
     beforeSend: function(xhr){ 
       xhr.withCredentials = true; 
     }, 
     success: function(response){ 

      $(response).find("status").each(function() { 
       // get the status code 
       var receiver_status = $(this).attr('code'); 

       if (receiver_status == 200) { 

        // change status bar message 
        $('#server_status').html('Renaissance Wireless Server: [200 Connected]'); 

        // step 2. get device count 
        get_device_count(my_guid); 

        // step 3.part 1 get the guid to be used as the application id 
        // var my_guid = guid(); 

        // step 3. part 2 connect to a service handler whatever that means 
        connect_service_handler(my_guid); 

       } 

       if (receiver_status == 400) { 

        // change status bar message 
        $('#server_status').html('Renaissance Wireless Server: [400 Bad Request]'); 

        // set timed re-check and store it 
        setTimeout(function(){get_server_status(my_guid);}, 12300); 

       } 

       if (receiver_status == 401) { 

        // change status bar message 
        $('#server_status').html('Renaissance Wireless Server: [401 Not Found]'); 

        // set timed re-check and store it 
        setTimeout(function(){get_server_status(my_guid);}, 12300); 
       } 

       if (receiver_status == 500) { 

        // change status bar message 
        $('#server_status').html('Renaissance Wireless Server: [500 Internal Server Failure]'); 

        // set timed re-check and store it 
        setTimeout(function(){get_server_status(my_guid);}, 12300); 

       } 

       if (receiver_status == 501) { 

        // change status bar message 
        $('#server_status').html('Renaissance Wireless Server: [503 Service Unavailable]'); 

        // set timed re-check and store it 
        setTimeout(function(){get_server_status(my_guid);}, 12300); 

       } 
       // pass the xml to the textarea 
       // $('#process').val('GetAccessPoints'); 
       // $('#show_errors_here').val(response); 

      }); 

     }, 
     error:function (xhr, ajaxOptions, thrownError){ 
      $('#server_status').html('Renaissance Wireless Server: [Connection Failure]'); 
      // alert(xhr.status); 
      // alert(thrownError); 
     } 
    }); 

    // set timed re-check and store it 
    // setTimeout(function(){get_server_status(my_guid);}, 12300); 
} 

$(document).ready(function() { 

    // step 3.part 1 get the guid to be used as the application id 
    var my_guid = guid(); 

    // step 1 validate 
    get_server_status(my_guid); 

    // step 2. get device count 
    get_device_count(); 

    // step 3.part 1 get the guid to be used as the application id 
    // var my_guid = guid(); 

    // step 3. part 2 connect to a service handler whatever that means 
    // connect_service_handler(my_guid); 


}); 
</script> 
</body> 
</html> 

Mi pregunta simplemente es ¿hay un plugin jquery diferente que debería estar usando, o me estoy acercando a esto mal?

gracias ...

+0

La razón por la cual esto tiene que ser una solución de cliente, es porque esta aplicación se instalará junto con el receptor inalámbrico y los dispositivos de mano. No será de ninguna manera cerca del servidor web, y no puedo permitir que las personas instalen/configuren un servidor web como parte del proceso de instalación/uso. Entonces necesito un enfoque de cliente para hacer toda la comunicación. Y dado que no sé flash, y adobe air permite la comunicación entre dominios, esto puede funcionar, si puedo resolverlo todo. : P – crosenblum

Respuesta

3

No entiendo totalmente el problema, por lo que es un poco difícil de hacer recomendaciones, pero al menos puede ayudar con algunas ideas diferentes de transporte.

Preguntar a jQuery que hacer comunicación de socket es lo que yo sé fuera del alcance de jQuery. jQuery realmente solo está utilizando XMLHttpRequest, que no va a funcionar para sockets persistentes.

Idea 1

¿Qué pasa con el uso de la clase de ActionScript zócalo http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/net/Socket.html

Se puede incrustar la película flash en su página html y llamarlo desde javascript http://www.hariscusto.com/programming/communication-between-javascript-and-actionscript-as3-and-vice-versa/

Idea 2

Usted También podría considerar node.js en el servidor web y el gran módulo socket.io para aprovechar websockets dentro del aire y luego hacer una comunicación bidireccional entre el cliente de aire y el servidor. socket.io tiene un excelente navegador de cliente además del soporte del servidor. Ver http://socket.io/

Aquí hay una publicación interesante en el Blog Techie de Fedex sobre el uso de jQuery junto con socket.io y el nodo.JS - http://spiritconsulting.com.ar/fedex/2010/11/events-with-jquery-nodejs-and-socket-io/

idea 3 (nuevo)

Hay un aire Javascript clase de corriente disponible para desarrolladores de HTML aire. Me tropecé cruzando aquí:

Inicio/HTML Guía del desarrollador de Adobe AIR/Redes y comunicación

http://help.adobe.com/en_US/air/html/dev/WSb2ba3b1aad8a27b0-181c51321220efd9d1c-8000.html

Hay varias API de socket diferentes en función de sus necesidades

+0

@orangeutancloud Si va a utilizar socket.io, también puede usar el socket.io que utiliza websockets nativos o larga polling o flash bridge cuando corresponda/compatible. – Raynos

+0

@Raynos, sí, buen punto. Debo decir en mi respuesta que esperar que jQuery haga sockets o encontrar un complemento que use sockets está pidiendo más de lo que jQuery puede hacer. El socket.io del cliente probablemente sea la solución más fácil si node.js es una opción en el servidor web. –

+0

@orangutancloud no es demasiado difícil escribir un contenedor para la API de websocket para decir asp.net o php o RoR. No necesita socket.io en el servidor. – Raynos

3

estoy trabajando en un plugin para jQuery para socket.io que creo que podría ayudarle a cabo:

https://github.com/williscool/jquery-socket.io

He estado trabajando en una aplicación que usa sockets web a través de socket.io desde hace un tiempo y ha funcionado bastante bien.

Échale un vistazo y cuéntame lo que piensas.

+1

excelente trabajo @Will! – Philip

+0

gracias! :) Realmente disfruté trabajando en eso. Me alegra que te guste – Will