From Ape Wiki

Jump to: navigation, search

There must be more discussion about browser compatibility. What setups have you tested this with?

Have you tested long polling and it only works with www.yoursite.com:433 and it does NOT work with ape03.yoursite.com:80???

---

The method is just dependant on the browser, not the site nor protocol.

Everything should work with Transport 0 (long polling). WebKit-based browsers (except Adobe Air) should work with Transport 1. Cross-domain usage (where the JSF is being loaded on a domain other than the server) should use JSONP transport, etc.

Here is (very simple) JSF for Adobe Air 2.5+ which does not use iframe, if you are using pre-2.5 you will have JSON problems unless you use as3corelib:

MyApp.Settings = {

 NAME : 'Login Name',
 INFO : 'Passed to login function and set as user.properties.info on server', // You don't even need this, just edit command queue below
 SERVER : 'http://ape.myserver.com:6969/?',
 CHANNELS : ['happeningnow','errorlog']

};

MyApp.Ape = function () {

 // Private
 var eventListeners = { "READY": [], "JOIN": [], "LEAVE": [], "CHANNEL": [], "DATA": [] };
 var properties = {};
 var pubid = ;
 var sessid = ;
 var challenge = 3;
 var commandqueue = [
   {'cmd': "CONNECT", 'chl': 1, 'params': { 'name': escape(MyApp.Settings.NAME), 'info': MyApp.Settings.INFO, 'transport': 0 } },
   {'cmd': "JOIN", 'chl': 2, 'params': {'channels': MyApp.Settings.CHANNELS }}
 ];
   
 function error ( code, text, debug ) {
   if ( text ==  ) text='Error communicating with server!';
   alert('Error ' + code + ': ' + text + (debug ? "\nDebug Info: " + JSON.stringify(debug) : ));
   air.trace('*** ERROR (' + code + '): ' + text);
   if ( debug ) air.trace('*** DEBUG: ' + JSON.stringify(debug));
 }
 function received ( d ) {
   var _self=this;
   var xhr = d.target;
   if ( xhr.readyState == 4 && xhr.responseText !=  ) { // If there is no responseText, we are in a long-polling state
     air.trace('<-- ' + xhr.responseText);
     var response = JSON.parse(xhr.responseText);
     for ( var i in response ) {
       var raw=response[i].raw || _error('INTERNAL 1','No RAW received',xhr);
       var data=response[i].data || _error('INTERNAL 2','No DATA received',xhr);
       if ( raw == "LOGIN" ) {
         if ( data.sessid !=  ) sessid=data.sessid;
       } else if ( raw == "IDENT" ) {
         if ( data.user && data.user.pubid ) { pubid=data.user.pubid; if ( data.user.properties ) properties=data.user.properties; }
         fireEvent("READY",data);
       } else if ( raw == "CHANNEL" ) {
         fireEvent("CHANNEL",data);
       } else if ( raw == "JOIN" ) {
         fireEvent("JOIN",data);
       } else if ( raw == "LEAVE" ) {
         fireEvent("LEAVE",data);
       } else if ( raw == "DATA" ) {
         fireEvent("DATA",data);
       } else if ( raw == "ERR" ) {
         error(data.code,data.value,data);
         return false; // This is to make sure we don't call connect() again
       } else {
         air.trace(raw,data); // I probably missed a few RAWS
       }
     }
     connect();
   } else if ( xhr.readyState == 4 && xhr.responseText ==  ) { // We hit the end of XHR timeout with no data (long polling finished), reconnect
     connect();
   }
 }
 function connect ( ) {
   var postdata={};
   if ( commandqueue.length < 1 ) {
     commandqueue.push( {'cmd': 'CHECK', 'sessid': sessid, 'chl': challenge} );
   }
   var xhr = new XMLHttpRequest();
 
   xhr.onreadystatechange = received;
   xhr.onerror = function(d,e,f){air.trace('*** XHR ERROR: ' + JSON.stringify(d) + ', ' + JSON.stringify(e));};
   xhr.httpIdleTimeout = 25000; // not working?
   xhr.open( "POST", MyApp.Settings.SERVER, true );
   xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=utf-8");
   air.trace('--> ' + JSON.stringify(commandqueue));
   xhr.send( JSON.stringify(commandqueue) );
   main_xhr=xhr;
   commandqueue=[];
   challenge++;
 }
 function send ( cmd, params ) {
   commandqueue.push({'cmd': cmd, 'sessid': sessid, 'params': params});
   main_xhr.abort(); // this makes the long polling stop, only to be restarted on the next line
   connect();
 }
 function fireEvent ( name, params ) {
   for ( var i in eventListeners[name] ) {
     if ( eventListeners[name][i] ) eventListeners[name][i].call(this,params);
   }
 }
    
 function addListener ( name, callback ) {
   if ( eventListeners[name] ) {
     air.trace('*** Adding event listener for event: ' + name);
     return eventListeners[name].push(callback);
   } else {
     air.trace('*** Unknown event listener ' + name);
     return false;
   }
 }
 // Public
 return {
   'init' : connect,
   'send' : send,
   'addListener' : addListener
 }

};

MyApp.Core = function(){

 var ape = new MyApp.Ape();
 function gotData ( data ) {
jQuery("div#content").append( "
" + data.msg + "
" );
 }
 function start ( ) {
   // Note this doesn't care which pipe/channel you got it from, YOU are in charge of pipe/channel management
   ape.addListener("DATA", gotData);
   ape.init();
 }
 return {
   init : start
 }

};

- Here is HTML for your AIR Project (I don't hide the window personally): -

<html> <head>

 <title>Error Log</title>
 <script type="text/javascript" src="app/js/jquery-1.6.2.js"></script>
 <script type="text/javascript" src="app/js/AIRAliases.js"></script>
 <script type="text/javascript" src="app/js/myapp.js"></script>
 <script type="text/javascript">
   var myapp=new MyApp.Core();
   myapp.init();
 </script>
 <style type="text/css">
 body {
   font-size: 0.9em;
   font-family: Courier, sans-serif;
   padding: 5px;
   background-color: #000000;
   color: #ffffff;
 }
 div#content {
   height: 460px;
   width: 100%;
 }
 </style>

</head> <body id="myapp">

</body> </html>

Good Luck! -mojoe