Levi Z has asked for the wisdom of the Perl Monks concerning the following question:

Dear, dear all,

I'm trying to learn everything myself but i cant figure out the best way to do the following.

I had/have..:

A Perl script on a raspberry pi that checks a website on the INTERNET every 3 seconds for updates... On the website is a number, say 1 or 2.. The Perl script does something depending on the 1 or the 2.


Now i want to reduce traffic so i would like this:

I still have 1 PHP webpage, now with 1 button. If i push this button a 1 magically turns into a 2 or the other way around. when this button is pressed a want to send a "trigger" to my RPi so my perl script can take over.. In this way my Perl script does not have to check the website like 26400 times a day and it still reacts fast.



I was thinking about a tcp packet?? I can when i start my Perl script, send my IP-adres to the website and store it in a DB to use later. If this could be the best option i found some examples but they are all different and the only thing 1 need is sending 1 digit or letter.. just a trigger.



Now my knowledge of php is 'ok', my Perl experience is from the last week and my TCP/IP knowledge is almost 0.
And my english maybe could be better but i'm from the Netherlands, so sorry for that :D
  • Comment on trigger perl script from remote php script.

Replies are listed 'Best First'.
Re: trigger perl script from remote php script.
by BrowserUk (Patriarch) on Jan 03, 2015 at 00:54 UTC

    Rather than TCP; use UDP.

    In your perl program you only need this to receive the notification:

    #! perl -slw use strict; use IO::Socket; socket( SOCKET, PF_INET, SOCK_DGRAM, getprotobyname('udp') ) or die "s +ocket: $!"; bind( SOCKET, sockaddr_in( 54321, inet_aton( 'localhost' ) ) ) or die +$!; my $input; while( 1 ) { my $addr = recv( SOCKET, $input, 1024, 0 ) or die $!; my( $port, $ipbin ) = sockaddr_in( $addr ); printf "Got '%s' from ip:%s port:%d\n", $input, inet_ntoa($ipbin) +, $port; }

    In your PHP program, you can use this to send the '1' or '2' when required.

    The Perl script above will block at the recv until it receives the datagram from your PHP program.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      ... and, if there is any possibility of UDP packets coming in a “surge,” consider noting the time-of-day when the last packet was responded-to, so as to ignore subsequent packets that arrive too soon thereafter.

Re: trigger perl script from remote php script.
by Perlbotics (Archbishop) on Jan 02, 2015 at 23:31 UTC

    Good idea to switch from polling to an event-driven mechanism.

    Following the TCP/IP path, you'll need a small daemon running on the RPi, e.g. by means of HTTP::Daemon. The triggers could be invoked from the PHP webpage by an HTTP GET or POST on specific URLs like http://<RPI-IP>/trigger/1 or http://<RPI-IP>/trigger/2. I assume, you want private access to the RPi? So, make sure, nobody else can run your scripts (e.g. HTTPS or SSH tunnel plus credentials).

    If you already have a webserver running on the RPi, have a look at CGI/FCGI or even PSGI. The latter leads to Twiggy, Dancer, Mojolicious, etc. I have to add, that I have never run one of these on an RPi, so take this advice with a little bit of caution - they should work for a low traffic scenario though.

Re: trigger perl script from remote php script.
by Levi Z (Initiate) on Jan 04, 2015 at 10:42 UTC
    So UDP is not gonna worl but TCP/IP seems to do :D

    In the end i was just trying out different example scripts but it worked..
    I will share what i did:

    I made this perl script on my RPi an ran it.
    use IO::Socket::INET; # auto-flush on socket $| = 1; # creating a listening socket my $socket = new IO::Socket::INET ( LocalHost => '0.0.0.0', LocalPort => '7777', Proto => 'tcp', Listen => 5, Reuse => 1 ); die "cannot create socket $!\n" unless $socket; print "server waiting for client connection on port 7777\n"; while(1) { # waiting for a new client connection my $client_socket = $socket->accept(); # get information about a newly connected client my $client_address = $client_socket->peerhost(); my $client_port = $client_socket->peerport(); print "connection from $client_address:$client_port\n"; # read up to 1024 characters from the connected client my $data = ""; $client_socket->recv($data, 1024); print "received data: $data\n"; # write response data to the connected client $data = "ok"; $client_socket->send($data); # notify client that response has been sent shutdown($client_socket, 1); } $socket->close();


    And ran this PHP script on my HOSTED server:

    <?php error_reporting(E_ALL); echo "<h2>TCP/IP Connection</h2>\n"; /* Get the port for the WWW service. */ $service_port = 7777; /* Get the IP address for the target host. */ $address = '82.10.291.11'; /* Create a TCP/IP socket. */ $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket === false) { echo "socket_create() failed: reason: " . socket_strerror(socket_l +ast_error()) . "\n"; } else { echo "OK.\n"; } echo "Attempting to connect to '$address' on port '$service_port'..."; $result = socket_connect($socket, $address, $service_port); if ($result === false) { echo "socket_connect() failed.\nReason: ($result) " . socket_strer +ror(socket_last_error($socket)) . "\n"; } else { echo "OK.\n"; } // $in = "HEAD / HTTP/1.1\r\n"; // $in .= "Host: www.example.com\r\n"; // $in .= "Connection: Close\r\n\r\n"; $in = '1234.4321.this finally works'; $out = ''; echo "Sending HTTP HEAD request..."; socket_write($socket, $in, strlen($in)); echo "OK.\n"; echo "Reading response:\n\n"; while ($out = socket_read($socket, 2048)) { echo $out; } echo "Closing socket..."; socket_close($socket); echo "OK.\n\n"; ?>


    Now i'm gonna combine these with my original scripts an secure them but i'm sure this wil work.

    THANK YOU KINDLY for thinking with me.
Re: trigger perl script from remote php script.
by Levi Z (Initiate) on Jan 04, 2015 at 00:17 UTC
    Well..

    I have been trying all day but i gess i do not have enough acces on my server to send udp packets tru php.. I am getting "Operation not permitted" in the php script.. :(

      You should really try a PHP site for solutions to PHP problems, but this seems to answer the implied question.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.