Shop OBEX P1 Docs P2 Docs Learn Events
Basic GET and POST Object [Updated 1/1/2011] - Page 2 — Parallax Forums

Basic GET and POST Object [Updated 1/1/2011]

2»

Comments

  • Mike GMike G Posts: 2,702
    edited 2011-03-04 07:31
    Roy E has some mighty fine RTC code. See the Google repository.
    i meant to give me an idea of where or how insert this function in your code and in the web page

    You would create a reference to Roy's object in the OBJ block, Initialize (or Start) the object, then invoke the methods. I beleive this is what you're asking? If so, there are excellent examples in the Propeller Education document. You can find the pdf in under help in the Propelller Tool. There is a section on Objects, COGs, and methods.

    If I get some time after work, I'll try to wire up an example.
  • JAGOJAGO Posts: 49
    edited 2011-03-04 09:30
    Hi mike,

    Many thanks... the answer is clear, i try to implement the code but equally i waiting for your example.. many thanks for all.

    greetings
  • pthartmannpthartmann Posts: 27
    edited 2011-03-15 14:42
    Hey Mike,

    I've successfully used your modified HttpRequest and HTTPServer to create, open, write, close, and delete an XML file, and repeat - while parsing it on the client side for dynamic data transmission. -Thank you.

    It seems to do this in reverse, write to an xml from the client side and then parse it on the Spinneret, one would need PHP or ASP(in conjunction with AJAX) like a typical server application.

    Which brought me back to how you passed the ledstate through your dynamic data handler. How are you using your ajaxhandler.aspx? Is this being hosted from the spinneret? Otherwise, would it be better to use the .shp via your MapMethod?

    Below is your Javascript I'm referencing:
    //XmlHttpRequest object
    var ledReq = getXmlHttpRequestObject();

    function setLed(ledstate) {
    //alert("ledstate: " + ledstate);
    if (ledReq.readyState == 4 || ledReq.readyState == 0) {
    //ledReq.open("GET", 'http://spinneret.servebeer.com:5000/shp.shp?ledstate=' + ledstate + '&ms=' + new Date().getTime(), true);
    ledReq.open("GET", 'http://www.agaverobotics.com/spinneret/ajaxhandler.aspx?ledstate=' + ledstate + '&ms=' + new Date().getTime(), true);
    ledReq.onreadystatechange = handleLedState;
    ledReq.send(null);
    state = ledstate;
    }
    }
    Thanks.
  • Mike GMike G Posts: 2,702
    edited 2011-03-15 17:57
    I've successfully used your modified HttpRequest and HTTPServer

    Cool... can you post the code?
    How are you using your ajaxhandler.aspx

    ajaxhandler.aspx is just a Web Request to shp.shp on the spinneret. IE and other browsers don't like cross domain scripts, they complain about spinneret.servebeer.com. I had to do that in order to server the web cam and the ajax from agaverobotics.com.
    Is this being hosted from the spinneret?

    No, ajaxhandler.aspx is hosted by agaverobotics.com
    Otherwise, would it be better to use the .shp via your MapMethod?

    The mapping works fine if the you're on the spinneret.servebeer.com domain and not going through another URL.
    It seems to do this in reverse, write to an xml from the client side and then parse it on the Spinneret, one would need PHP or ASP(in conjunction with AJAX) like a typical server application.
    Not sure what you mean. I write dynamic content to RAM by invoking a method with the same name as the requested file, append/write write content to a temp file, then serve up the temp file.
  • pthartmannpthartmann Posts: 27
    edited 2011-03-17 15:38
    Hey Mike, still working on the code, but I should have something suitable to post here soon.
  • pthartmannpthartmann Posts: 27
    edited 2011-03-21 12:53
    In the main loop I call SetupXML - the following shows the PRI's that are called. I have also attached the .htm that parses the created XML. As of right now, one can see that the process simply deletes and creates a new send.xml every time. I know this would be more efficient to simply erase the send.xml, however I haven't figured that out yet. Quadformer3 is the edited HTTPServer.spin -

    For demonstration, we used a counting variable - numvar, although soon we will have sensor values that fulfill each value in our table.

    The webpage constantly reloads, parses, and displays send.xml, we also have a video stream that works concurrently above this. The files simply need to be copied onto the sdcard.
    PRI SetupXML
    
        SDCard.changeDirectory(@approot)
        SDCard.deleteEntry(string("send.xml"))
        SDCard.newFile(string("send.xml"))
        WriteSend(string("<?xml version=", QUOTE, "1.0", QUOTE, " encoding=", QUOTE, "ISO-8859-1", QUOTE, "?>", Request#CR))
        WriteSend(string("<CATALOG>", Request#CR))
        WriteSend(string("        <DATA>", Request#CR))
        WriteSend(string("              <A_X>"))
        WriteSend(Request.NumberToAsccii(numvar))
        WriteSend(string("</A_X>", Request#CR))
        WriteSend(string("              <A_Y>"))
        WriteSend(Request.NumberToAsccii(numvar))
        WriteSend(string("</A_Y>", Request#CR))
        WriteSend(string("              <A_Z>"))
        WriteSend(Request.NumberToAsccii(numvar))
        WriteSend(string("</A_Z>", Request#CR))
        WriteSend(string("              <R_D>"))
        WriteSend(Request.NumberToAsccii(numvar))
        WriteSend(string("</R_D>", Request#CR))
        WriteSend(string("              <P_D>"))
        WriteSend(Request.NumberToAsccii(numvar))
        WriteSend(string("</P_D>", Request#CR))
        WriteSend(string("              <Y_D>"))
        WriteSend(Request.NumberToAsccii(numvar))
        WriteSend(string("</Y_D>", Request#CR))
        WriteSend(string("              <A_I>"))
        WriteSend(Request.NumberToAsccii(numvar))
        WriteSend(string("</A_I>", Request#CR))
        WriteSend(string("              <B>"))
        WriteSend(Request.NumberToAsccii(numvar))
        WriteSend(string("</B>", Request#CR))
        WriteSend(string("              <H>"))
        WriteSend(Request.NumberToAsccii(numvar))
        WriteSend(string("</H>", Request#CR))
        WriteSend(string("              <L>"))
        WriteSend(Request.NumberToAsccii(numvar))
        WriteSend(string("</L>", Request#CR))
        WriteSend(string("              <B_L>"))
        WriteSend(Request.NumberToAsccii(numvar))
        WriteSend(string("</B_L>", Request#CR))
        WriteSend(string("              <S_F>"))
        WriteSend(Request.NumberToAsccii(numvar))
        WriteSend(string("</S_F>", Request#CR))
        WriteSend(string("        </DATA>", Request#CR))
        WriteSend(string("</CATALOG>", Request#CR))
        'PauseMSec(200)
     return
         
    PRI WriteSend(dataPtr)
    
        SDCard.openFile(string("send.xml"), "a")
        SDCard.writeData(dataPtr, strsize(dataPtr))
        SDCard.closeFile
    
    So short term goals are to make the send process more efficient, and of course to implement a way to append an XML file, initiate a receive process, from the client side.
  • bsnutbsnut Posts: 521
    edited 2011-03-22 09:01
    @Mike,

    Thanks for posting the code for the Spinneret and it gives an example for what I need to do for my ship monitoring system.
  • pthartmannpthartmann Posts: 27
    edited 2011-03-24 20:07
    Well... I can receive data using the refreshing XML method. I can now also send data using the shp method.

    My problem is creating an AJAX management system for the two. Each process runs fine by itself.

    I've found ways to do this with jquery.js - there's also a cool program called ajaxManager:
    http://www.protofunc.com/scripts/jquery/ajaxManager/

    This would effectively mean, however, that I would have to completely rethink both the AJAX functions I have now - in order to get them into the correct jquery and ajaxManager format.
  • Mike GMike G Posts: 2,702
    edited 2011-03-24 20:22
    My problem is creating an AJAX management system for the two.
    What does this mean?
    I've found ways to do this with jquery.js - there's also a cool program called ajaxManager

    Be careful the jquery libs are kinda big.
  • pthartmannpthartmann Posts: 27
    edited 2011-03-25 10:17
    Mike G wrote: »
    What does this mean?

    Your setled function calls function getXmlHttpRequestObject() which creates a new request object:
    [HTML]var ledReq = getXmlHttpRequestObject();[/HTML]My XML parsing function (loadXMLDoc(url)) also creates, continuously, a new request object.

    My understanding is that these two AJAX processes - with their own object requests, are conflicting. Each time [HTML]new XMLHttpRequest(); [/HTML] is called, it interferes with the other process.
    Mike G wrote: »
    Be careful the jquery libs are kinda big.

    That was my concern too. I think it should be okay.
    The current jquery-1.5.1.js is 212KB uncompressed - LINK:jquery-1.5.1.js

    -You can also include it as an url:
    [HTML]<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>[/HTML]-I also believe most web browsers will store the .js in the cache.
    However, when sending new data to and from a webpage, I'm assuming most of us don't want to cache that data - once again I think jquery could be the answer as it makes it simple to turn off caching AJAX.
  • Mike GMike G Posts: 2,702
    edited 2011-03-25 11:05
    My understanding is that these two AJAX processes - with their own object requests, are conflicting. Each time

    Not if you abstract the methods a little more... You can have as many XmlHttpRequestObject() objects, members, and call back as you like. I do this with a Fantasy Football draft application. As a matter of fact, I copied the Fantasy Football code to the Spinneret app. Anyway the Fantasy Football main panel is constantly being updated (every 5 seconds) from input by remote users. Not only that but different sections of the page are updated depending on what's going on, like chat (instant). So I know it can be done. It just a matter of abstracting your code.
  • pthartmannpthartmann Posts: 27
    edited 2011-03-30 19:44
    I've tried reaching out on JavaScript/AJAX forums, but no one's bit, yet.
    I probably should have mentioned that I've never programmed JavaScript before. To abstract the functions, would you recommend a particular approach, such as conditional if - then logic?

    I'm starting to wonder if part of the problem is the refresh rate I have on the XML parsing function. Right now it updates about every second. Again this works fine by itself, but not with the other function.

    Would you be able to share an example from your Fantasy Football draft code?

    I'll include the code - which is very much a work-in-progress right now, for reference.
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <html>
    <head>
    <style type=text/css>
    DIV {COLOR: #009900; }
    </style>
    <TITLE>Universal Ground Station</TITLE>
    
    <script type="text/javascript">
        var state = 4;
    
    function ajax_object() {
            if (window.XMLHttpRequest) {
                return new XMLHttpRequest();
            } else if(window.ActiveXObject) {
                return new ActiveXObject("Microsoft.XMLHTTP");
            } else {
                alert("Your Browser does not support AJAX!\nTry Firefox?");
            }
        }
        
        function ajax_request(url, data, callback)
    {
      var xhrobj = ajax_object();
      xhrobj.open("GET", url);
      xhrobj.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 
     
      xhrobj.onreadystatechange = function()
      {
        if (xhrobj.readyState == 4 && xhrobj.status == 200)
        {
          if (xhrobj.responseText)
          {
              callback(xhrobj.responseText);
          }
        }
      };
      xhrobj.send(data);
    }
        
        //XmlHttpRequest object
        var directionReq = ajax_object();
    
        function setdirection(directionstate) {
            state = directionstate;
            //alert("directionstate: " + directionstate);
            if (directionReq.readyState == 4 || directionReq.readyState == 0) {
                //ajax_request('http://192.168.1.120/shp.shp?directionstate=' + directionstate + '&ms=' + new Date().getTime(), null, function(data){ return });
                directionReq.open("GET", 'http://192.168.1.120/shp.shp?directionstate=' + directionstate + '&ms=' + new Date().getTime(), true);
              
                directionReq.onreadystatechange = handledirectionState;
                directionReq.send(null);
                state = 4;
            } 
        }
    
        function handledirectionState() {
    
            if (directionReq.readyState == 4) {
                
                var div = document.getElementById('directionStatusIndicator');
                var str = directionReq.responseText;
                //alert("response: " + directionReq);
                div.innerHTML = str;
    
                if ((typeof(str) == 'undefined') || (str == '')) {
                    if (state > '0') {
                        div.innerHTML = "<strong style='color:orange;font-size:26px;'>On</strong>";
                    } else {
                        div.innerHTML = "<strong style='color:gray;font-size:26px;'>Waiting for input</strong>";
                }
            } else {
                div.innerHTML = str;
            }
            }
        }
    var xmlhttp = ajax_object();    
    function loadXMLDoc(url)
    {
    
    var txt,x,xx,i, j;
    //ajax_request("send.xml", null, function(data){ return });
    xmlhttp.onreadystatechange=function()
      {
      if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
        txt="<table border='1'><tr><th>Acceleration X</th><th>Acceleration Y</th><th>Acceleration Z</th><th>Roll Degrees</th><th>Pitch Degrees</th><th>Yaw Degrees</th></tr>";
        x=xmlhttp.responseXML.documentElement.getElementsByTagName("DATA");
        for (i=0;i<x.length;i++)
          {
          txt=txt + "<tr>";
          xx=x[i].getElementsByTagName("A_X");
            {
            try
              {
              txt=txt + "<td>" + xx[0].firstChild.nodeValue + "</td>";
              }
            catch (er)
              {
              txt=txt + "<td> </td>";
              }
            }
          xx=x[i].getElementsByTagName("A_Y");
            {
            try
              {
              txt=txt + "<td>" + xx[0].firstChild.nodeValue + "</td>";
              }
            catch (er)
              {
              txt=txt + "<td> </td>";
              }
            }
            xx=x[i].getElementsByTagName("A_Z");
            {
            try
              {
              txt=txt + "<td>" + xx[0].firstChild.nodeValue + "</td>";
              }
            catch (er)
              {
              txt=txt + "<td> </td>";
              }
            }
            xx=x[i].getElementsByTagName("R_D");
            {
            try
              {
              txt=txt + "<td>" + xx[0].firstChild.nodeValue + "</td>";
              }
            catch (er)
              {
              txt=txt + "<td> </td>";
              }
            }
            xx=x[i].getElementsByTagName("P_D");
            {
            try
              {
              txt=txt + "<td>" + xx[0].firstChild.nodeValue + "</td>";
              }
            catch (er)
              {
              txt=txt + "<td> </td>";
              }
            }
            xx=x[i].getElementsByTagName("Y_D");
            {
            try
              {
              txt=txt + "<td>" + xx[0].firstChild.nodeValue + "</td>";
              }
            catch (er)
              {
              txt=txt + "<td> </td>";
              }
            }
          txt=txt + "</tr>";
          }
          
        txt=txt + "</table>";    
        
        document.getElementById('txtDATAInfo').innerHTML=txt;
        
            txt="<table border='1'><tr><th>Altitude in Inches</th><th>Behavior</th><th>Heading</th><th>Location</th><th>Battery Life</th><th>Sensor Feedback</th></tr>";
        x=xmlhttp.responseXML.documentElement.getElementsByTagName("DATA");
        for (j=0;j<x.length;j++)
          {
              
          txt=txt + "<tr>";
          xx=x[j].getElementsByTagName("A_I");
            {
            try
              {
              txt=txt + "<td>" + xx[0].firstChild.nodeValue + "</td>";
              }
            catch (er)
              {
              txt=txt + "<td> </td>";
              }
            }
          xx=x[j].getElementsByTagName("B");
            {
            try
              {
              txt=txt + "<td>" + xx[0].firstChild.nodeValue + "</td>";
              }
            catch (er)
              {
              txt=txt + "<td> </td>";
              }
            }
            xx=x[j].getElementsByTagName("H");
            {
            try
              {
              txt=txt + "<td>" + xx[0].firstChild.nodeValue + "</td>";
              }
            catch (er)
              {
              txt=txt + "<td> </td>";
              }
            }
            xx=x[j].getElementsByTagName("L");
            {
            try
              {
              txt=txt + "<td>" + xx[0].firstChild.nodeValue + "</td>";
              }
            catch (er)
              {
              txt=txt + "<td> </td>";
              }
            }
            xx=x[j].getElementsByTagName("B_L");
            {
            try
              {
              txt=txt + "<td>" + xx[0].firstChild.nodeValue + "</td>";
              }
            catch (er)
              {
              txt=txt + "<td> </td>";
              }
            }
            xx=x[j].getElementsByTagName("S_F");
            {
            try
              {
              txt=txt + "<td>" + xx[0].firstChild.nodeValue + "</td>";
              }
            catch (er)
              {
              txt=txt + "<td> </td>";
              }
            }
          txt=txt + "</tr>";
          }
          
        txt=txt + "</table>";
        
        
            document.getElementById('txtDATA2Info').innerHTML=txt;
        }
      }
    xmlhttp.open("GET",url,true);
    xmlhttp.send();
    }
    function begin(a)
    {
    state = a
    if (state == '0') {(setdirection(0));}
    else if (state == '1') {
        clearInterval(refreshIntervalId);
        (setdirection(1));
        }
    else if (state == '2') {
        clearInterval(refreshIntervalId);
        (setdirection(2));
        }
    else if (state == '3') {
        clearInterval(refreshIntervalId);
        (setdirection(3));
            }
    else {
        var refreshIntervalId = (setInterval("loadXMLDoc('send.xml')",1100));
        }
    //else {}
    
    }
    </script>
    </head>
    <body bgcolor="#000000" onLoad="begin(4);">
    <div align=center><table border="10"cellpadding="0"cellspacing="1"width="640"height="480"><tr><td bgcolor="white"align="center"valign="middle"><img src="http://192.168.1.101:8070/video.mjpg"></td></tr></table></div><br>
    <div align=center>      <input type="button" name="Up" value="Up" onclick="begin(0)" /><br>
                            <input type="button" name="Left" value="Left" onclick="begin(1)" />
                            <input type="button" name="Right" value="Right" onclick="begin(2)" /><br>
                            <input type="button" name="Down" value="Down" onclick="begin(3)" />
                            
                            <div id="directionStatusIndicator"><strong style="color:green">Waiting for input.</strong> </div>
    </div><br>                        
    <div align="center" id="txtDATAInfo">
    </div><br>
    <div align="center" id="txtDATA2Info">
    </div>
    
    </body>
    </html>
    
  • Mike GMike G Posts: 2,702
    edited 2011-03-30 21:36
    Looks ok... I'd dump
        function begin(a) {
            state = a
            if (state == '0') { (setdirection(0)); }
            else if (state == '1') {
                clearInterval(refreshIntervalId);
                (setdirection(1));
            }
            else if (state == '2') {
                clearInterval(refreshIntervalId);
                (setdirection(2));
            }
            else if (state == '3') {
                clearInterval(refreshIntervalId);
                (setdirection(3));
            }
            else {
                var refreshIntervalId = (setInterval("loadXMLDoc('send.xml')", 1100));
            }
            //else {}
    
            }
    

    and just call the functions directly.
    <div align=center>
      <input type="button" name="Up" value="Up" onclick="setdirection(0)" />
      <br>
      <input type="button" name="Left" value="Left" onclick="setdirection(1)" />
      <input type="button" name="Right" value="Right" onclick="setdirection(2)" />
      <br>
      <input type="button" name="Down" value="Down" onclick="setdirection(3)" />
      <div id="directionStatusIndicator"><strong style="color:green">Waiting for input.</strong> </div>
    </div>
    

    Is there a problem with the Spinneret method, shp.shp. I made shp.shp after a few beers...

    Have you tried executing setdirection() without loading the xml?
    var refreshIntervalId = (setInterval("loadXMLDoc('send.xml')",1100));
    

    What does not work? Can you hit setdirection()? Does the callback, handledirectionState(), fire?
        var directionReq = ajax_object();
    
        function setdirection(directionstate) {
            state = directionstate;
    
            //alert('setdirection(' + directionstate + ')');
            //return;
    
            //alert("directionstate: " + directionstate);
            if (directionReq.readyState == 4 || directionReq.readyState == 0) {
                //alert('test');
                directionReq.open("GET", 'http://192.168.1.120/shp.shp?directionstate=' + directionstate + '&ms=' + new Date().getTime(), true);
    
                directionReq.onreadystatechange = handledirectionState;
                directionReq.send(null);
                state = 4;
                
            }
        }
    
        function handledirectionState() {
    
            if (directionReq.readyState == 4) {
    
                var div = document.getElementById('directionStatusIndicator');
                var str = directionReq.responseText;
                alert(str);
    
                //alert("response: " + directionReq);
                //div.innerHTML = str;
    
    //            if ((typeof (str) == 'undefined') || (str == '')) {
    //                if (state > '0') {
    //                    div.innerHTML = "<strong style='color:orange;font-size:26px;'>On</strong>";
    //                } else {
    //                    div.innerHTML = "<strong style='color:gray;font-size:26px;'>Waiting for input</strong>";
    //                }
    //            } else {
    //                div.innerHTML = str;
    //            }
            }
        }
    
  • pthartmannpthartmann Posts: 27
    edited 2011-03-31 07:34
    setdirection() with your shp.shp works well- I really didn't change much from your setled() function
    I need to send you some more beer :lol:

    Also, the loadxml() function works well. It's only when I try to run them together I have issues.

    Therefore I've tried many approaches to abstracting the functions. That's why the begin() function may look odd. I have the loadxml() "reloading" via the setinterval command(that's how I've been able to have somewhat real time data off the Spinneret), so my last attempt was to clear the interval every time a call for the setdirection() came through.
  • Mike GMike G Posts: 2,702
    edited 2011-03-31 09:53
    You have to systematically troubleshoot. I'm not sure if the problem is on the Spinneret, the web page, or a combination. You know that both function work on their own, right?

    Set the interval to something large like 10 seconds and test.
    Use the serial terminal to verify state and execution path on the Prop.

    If the xml request is blocking the setdirection() function you can do something like set a semaphore see the code example below. You have to change the URL!
    <script type="text/javascript">
        var state = -1;
        var semaphoreId = 0;
        var count = 0;
    
        function ajax_object() {
            if (window.XMLHttpRequest) {
                return new XMLHttpRequest();
            } else if (window.ActiveXObject) {
                return new ActiveXObject("Microsoft.XMLHTTP");
            } else {
                alert("Your Browser does not support AJAX!\nTry Firefox?");
            }
        }
    
    
        //XmlHttpRequest object
        var directionReq = ajax_object();
    
        function setdirection(directionstate) {
            state = directionstate;
            var timeout = 0;
            //alert('setdirection(' + directionstate + ')');
            //return;
    
            while (semaphoreId == 1)
            {
                if(timeout++ > 100000) {
                    alert('Timeout in setdirection: ' + timeout);
                    // Clean up
                    return;
                    }        
            }
            
    
            //alert("directionstate: " + directionstate);
            if (directionReq.readyState == 4 || directionReq.readyState == 0) {
                //alert('test');
                directionReq.open("GET", 'http://localhost/agaverobotics/spinneret/myip.aspx?directionstate=' + directionstate + '&ms=' + new Date().getTime(), true);
    
                directionReq.onreadystatechange = handledirectionState;
                directionReq.send(null);
            }
        }
    
        function handledirectionState() {
    
            if (directionReq.readyState == 4) {
    
                var div = document.getElementById('directionStatusIndicator');
                var str = directionReq.responseText;
                //alert(str);
    
                //alert("response: " + directionReq);
                //div.innerHTML = str;
    
                div.innerHTML = 'handledirectionState: ' + state;
            }
        }
    
        
    
        var xmlhttp = ajax_object();
        function loadXMLDoc(url) {
    
            semaphoreId = 1;
            
            //alert('loadXMLDoc');
            //return;
            if (xmlhttp.readyState == 4 || xmlhttp.readyState == 0) {
                xmlhttp.onreadystatechange = handleLoadXMLDoc;
    
                xmlhttp.open("GET", 'http://localhost/agaverobotics/spinneret/myip.aspx?ms=' + new Date().getTime(), true);
                xmlhttp.send(null);
            }
        }
    
        function handleLoadXMLDoc() {
    
            if (xmlhttp.readyState == 4) {
    
                var div = document.getElementById('txtDATAInfo');
                div.innerHTML = 'handleLoadXMLDoc ' + count++;
            }
            semaphoreId = 0; 
        }
    
    
        var refreshIntervalId = (setInterval("loadXMLDoc('send.xml')", 1100));
    
    </script>
    
Sign In or Register to comment.