5

I would need to check the value of a IO pin in realtime over the LAN. Since I need to do it from differnet devices (pc, palm, iphone, Samsung galaxy etc) I was thinking of a webpage. The value can be at maximum 0.5 seconds old. And has to refresh itself continuously. How can this be done?

  • 3
    It's possible. The predominant way to do this now is with websockets (this page is live updated that way), although you can also use AJAX long-polling. – goldilocks Dec 10 '13 at 16:10
  • +1 @goldilocks -- Could you post that as an answer, please, so we can properly upvote you? ;) – n.st Dec 10 '13 at 17:17
  • Thank you! could you please post it as an answer? maybe with a very simple short sample i can start with would be even better! thank you! – user2452250 Dec 10 '13 at 17:43
  • 1
    @n.st Done! This is a fairly broad topic, so I tried to sketch a reasonable introduction. – goldilocks Dec 11 '13 at 12:03
8

In order to get a web page to update itself, you need to communicate back to the server from the client without the user doing anything (and remember, web relations mean the server can't send the client anything until the client asks for it). There are a few different mechanisms you can use to do this:1

  • Java applets. Applets are great, but unfortunately a long history of security problems and other technical issues hampered their acceptance and today they aren't used much, and some mobile platforms (e.g. Android) don't support them at all.

  • Flash. Adobe has obsoleted flash because of HTML 5, but it's still widely used and available in most if not all browsers. I assume Microsoft Silverlight has similar capabilities to flash here, but it has even less broswer support than Java.

  • Javascript. Javascript is ubiquitous and standard on all modern browsers. It's also better integrated with normal HTML content than the other things in this list.

Javascript is probably the way to go, so here's some suggestions involving that:

  • Timer: This is the simplest method, but also the clunkiest, most limited, and least likely to work well. You add this to the HTML <body> somewhere:

    <script type="text/javascript">
        setTimeout (
            function() { window.location.reload(); },
            500
        )
    </script>
    

    This just reloads the page every 500 milliseconds; each time the server would generate content dynamically. Here's a reference for js timers. If you do this, you want the page url itself to be non-cachable, but any CSS files and images to be cached. It still won't be the most bandwidth friendly method, but unless the page is huge the difference between this and ajax shouldn't be too great.

  • AJAX requests: These can happen behind the scenes to contact the server. You could do this with a timer; the repetitive version of setTimer() is setInterval(), although you are probably better off calling setTimer() repeatedly when the data returns. AJAX implementations can differ slightly from browser to browser, so it's a good idea to use a portable library such as jquery. Here's an example of a jquery based ajax request:

    $.ajax ({
        url: /request/path,
        success: function (data) {
            // Update the page with 'data'
        }
    })
    

    An alternative to using a timer would be to use long-polling, whereby you send a request to the server, the server times the response, then as soon as you receive it, you send another request. Actually getting a 1/2 second timing over the WWW this way won't be easy, but it should be fine on a local LAN.

  • Websockets: The web socket protocol is fairly recent but widely supported -- the live updates on this site are done with web sockets.2 It allows you to make a persistent two-way direct connection to the server, meaning both parties can send and receive data arbitrarily. This requires it to be event driven, like many things in javascript. You would create a new websocket client side in js like this:

    var wsock = new WebSocket("ws://localhost/foo/bar");
    

    Obviously, you need server side support too. I would assume all mainstream HTTP servers, and the various technologies commonly used with them (PHP, django, catalyst, ruby on rails, java, whatever)3 have some implementation. You can't do this via CGI as it is actually not an HTTP exchange. Getting back to the client side, the Websocket object uses callbacks to handle events:

     wsock.onmessage = function (data) {
          // Update the page here
     }
    

    That responds to a message sent from the server. Since this is two-way, the client doesn't have to request anything, but if you do want to send a message to the server: wsock.send(text). A websocket is by far the most bandwidth friendly method because the messages by-pass the need for an HTTP header. It should also give the best latency and most precise timing because it is guaranteed to be a persistent socket connection.

    Unfortunately, because this is a newer technique than the other two, it's the least documented. The W3C draft version of the client side API is here. I recommend you look around for tutorials or references involving your preferred server side language/technology and work from there. The client stuff is about as simple as what's shown here; the server side should be a reciprocal of that.


1. Not mentioned is the meta refresh header (see HeatFanJon's answer); this is functionally the same as the javascript timer but the granularity is in seconds.

2. If you have a specific mobile browser you like to use you should investigate that first -- and don't rely on this page working as a sign, because I think it falls back on long-polling if websockets aren't available. There is a test site here; notably the basic Android browser doesn't support it (but chrome and firefox on android do). Safari on IOS works.

3. The server-side implementation I've used myself is a custom one (the specification is not complex), but I did some googling of popular web frameworks (catalyst = perl, django = python) to see what's available; they all have something. However, traditional web servers like apache were not intended to deal with two way persistent connections, and it looks like apache's official support for it may be via proxying to another backend server, which is not a bad thing. Some of the modules (e.g. "tornado" for python) will make this simple enough; if the purpose of the server is mostly just this, you could just implement a simple, event based HTTP server in python/perl/PHP/ruby using the a websocket module and skip apache altogether.

  • Server Sent Events is another possible option and really quite simple to implement. This is of course a JavaScript alternative to websockets. Remy Sharp has an article here. – pedro_sland Dec 12 '13 at 16:30
  • 2
    Sorry, bad wording. I mean SSE requires JS (like Websockets) but unlike Flash, Java and meta refresh. I don't think anyone runs VBScript any more :) - at least not in a browser. Thank goodness. SSE/EventSource is a specification supported by modern browsers. No IE though but Remy Sharp has a polyfill and Yaffle wrote one too. – pedro_sland Dec 13 '13 at 19:00
  • @pedro_sland : Not bad wording, just ambiguous -- obviously I read "JavaScript alternative to websockets" the wrong way. All apologies! I've confusingly and irreversibly deleted my comment from the middle above, so double sorry to the reader, lol. – goldilocks Dec 14 '13 at 14:10
  • Yes, I read it later and thought "no wonder you got the wrong idea!" :) – pedro_sland Dec 15 '13 at 14:35
  • 1
    You don't have to use node, no. I've attached some links in the websockets section; the PHP one is to another answer and there are four different PHP websocket libraries there. If you are using python to check the pin, you could also just work directly in python -- search for "python tornado server websockets". If the server side stuff looks like it is going to involve more complications than you want, use the AJAX method instead; this is about the same amount of work client side if you use jquery, and easier server side since it is just a normal request. – goldilocks Dec 16 '13 at 14:23
1

Use a bash CGI script to run a program that reads the IO value and outputs the result to STDOUT. The bash script will add the HTML meta tag using the refresh property which tells the browser to reload the page after the number of seconds specified.

Check here for more detail on meta refresh. You can use this to also redirect to another web page.

$ cd /usr/lib/cgi-bin
$ vi read-io.cgi

Input the source below:

#!/bin/bash
echo "Content-type: text/html"
echo ""
echo "<html><head><title>IO Value</title>"
# Add meta refresh to cause the page to be reloaded every second
echo "<meta http-equiv="refresh" content="1" />"
echo "</head><body>"
echo "<h1>IO Value is"
# the line below is to execute the program that reads the
# IO value and outputs the result to STDOUT which will be
# returned in this HTTP response.  <path-to> is the path
# to the io-read executable 
/<path-to>/io-read
echo "</h1></body></html>"

Save and close the file. Setup execute permission on the script:

$ chmod +x read-io.cgi

You will need to installed Apache2 on your Pi to do this. You would access this web page as http://localhost/cgi/read-io.cgi

  • I think the question is about how to get the information on the page to auto-refresh at half second intervals. – goldilocks Dec 11 '13 at 10:48
  • Ah, it's a kludge but meta refresh can do that ... <meta http-equiv="refresh" content="1"> – HeatfanJohn Dec 11 '13 at 15:10
  • I didn't know about that one -- it's tidier than my javascript timer, although you can't get the 0.5 second granularity. +1 – goldilocks Dec 11 '13 at 15:18
0

You say you are thinking of a web page. There is an alternative: I would write a small process to run on the RPi.

One thread would read the GPIO and retain their status locally.

Other threads would act as a server for the Streaming Text Oriented Messaging Protocol (STOMP). Clients would connect to a port on this server over the LAN. The server would then feed a GPIO status message to the subscribed clients every 0.5 seconds.

There is plenty of example code in various languages available for both client and server. You should be able to find it easily with your favourite search engine.

  • AFAICT STOMP is not HTTP based and therefore could not be used in a web page... – goldilocks Dec 10 '13 at 16:08
  • That's right. STOMP is not HTTP. I've edited the answer to give a bit more detail. – Chenmunka Dec 10 '13 at 16:27
  • Unless there are generic STOMP clients for android and IOS (I don't find evidence of any with a quick search) this means having to code a client for each required device. The point of using a web-app would be that those devices all already have a browser, so you can use the same, relatively minimal, client side code for everything. – goldilocks Dec 10 '13 at 16:55
0

This fair reloads the page each 500 milliseconds; each time the server would create content progressively. Here's a reference for js clocks. On the off chance that you do this, you need the page url itself to be non-cachable, yet any CSS records and pictures to be reserved. Regardless it won't be the most transfer speed well disposed technique, however except if the page is immense the contrast among this and ajax shouldn't be excessively extraordinary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.