PHP / JS / Bash script for receiving GPS data over UDP

I want to write my own, small website for controlling my own GPS localizers. The problem is, that they are sending data (over GPRS) using UDP, not HTTP protocol. Can anyone give me any advice on how to receive such data and put it into MySQL database?

I'm looking for something exactly as written in this answer to that question. The only problem is that site mentioned in this answer has expired and script is unavailable.

All I need is an advice or example on how can I receive UDP packet/datagram containing coordinates, speed, date etc. and put this data into MySQL database. How to write a gateway as easiest as possible? All the rest I can handle myself.

I could do this without problems on Windows, as I'm former Delphi developer and writing a gateway between UDP and MySQL isn't a hard job to do there. But I need to run this solution (gateway) on a small, week Linux-based server, which isn't able to run Kylix (Delphi for Linux) programs, so this way is a dead-end.

Can this be done using PHP, JavaScript or by writing Bash script? I was thinking about node.js, which has similar example on home webpage (and probably many more out in the Internet). But I'm not to familiar with node.js, therefore I don't know, if there aren't better/easiers ways to do this.

It's possible to read data from UDP port using PHP. I am posting a example code which reads data from udp port.

<?php
    error_reporting(E_ALL | E_STRICT);

    $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
    socket_bind($socket, '127.0.0.1', 1223);

    $from = '';
    $port = 0;
    socket_recvfrom($socket, $buf, 12, 0, $from, $port);

    echo "Received $buf from remote address $from and remote port $port" .                                              PHP_EOL;
?>

and to insert that data into MySQL database may be you need to use a daemon, go through this link http://phpdaemon.net/

Maybe socket_recvfrom might interest you?

Here is, what I found myself.

General

As Venkat wrote, you can write a simple listner in pure PHP. You only have to run it via SSH, in PHP in CLI SAPI mode, not via browser, as it will fail on timeout after about 3-5 minutes.

For running in CLI mode, you need to know a full path to PHP and you have to call it with proper switch. For example:

/mnt/ext/opt/apache/bin/php -f /share/Web/projects/gps/gateway.php

PHP CLI does not use stdout for echo (don't know, what it uses). So, replace any echo with storing values to file or database, to see actual effects of your listner working.

You may need to use set_time_limit(0) function for endless, uninterrupted execution; but it was reported (see user contributed notes here), it is hardcoded to 0 for CLI SAPI, so setting this may not be mandatory.

After running your script in CLI mode, you can break it, by using Ctrl+C.

Listner example

Here is an example of a listner, that drops everything, it receives into 'drop.txt' file in the same directory, where script file is placed:

error_reporting(E_ALL | E_STRICT);

$file = './dump.txt';

$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($socket, '0.0.0.0', 12345);

while(TRUE)
{
    $buf = '';
    $from = '';
    $port = 0;

    socket_recvfrom($socket, $buf, 1024, 0, $from, $port);

    $momentum = time();

    $entry = $momentum.' -- received "'.trim($buf).'" from '.$from.' on port '.$port.PHP_EOL;

    file_put_contents($file, $entry, FILE_APPEND | LOCK_EX);
}

Things, you should keep in mind:

  1. This script uses infinite loop, so the only way to break it after running is to cast Ctrl+C.

  2. Use 0.0.0.0 IP address in socket_bind to listen from all sources (IP addresses) or 127.0.0.1 to limit it to localhost only.

  3. Carefully select third parameter in socket_recvfrom -- a maximum number of bytes that will be received -- to make sure that the data you're waiting for will not be truncated.

  4. You must use full path to files, you're using -- that is why there is $file = './dump.txt', not $file = 'dump.txt' in the code. Without full path, it can only work via webbrowser.

Using database

If you decide to drop recevied UDP packets into database and you choose SQLite for this purpose, you not only have to provide full path to database file, but also an absolute path! So:

$dbhandle = new SQLiteDatabase('/share/Web/projects/gps/data.db');

not:

$dbhandle = new SQLiteDatabase('data.db');

or even:

$dbhandle = new SQLiteDatabase('./data.db');

Second and third attempt will fail on some systems (depending on PHP configuration) and in this case, you'll see warning, that there is no such table, you're looking for, in database file.

Logoff problem fix

If you don't have direct access to the machine, on which you'll be running that listener, and you're connecting via SSH, keep in mind, that your listener will be problably turned off, once you logoff.

To fix this problem, you have to either run your PHP script in daemon mode (by adding & at the end):

/mnt/ext/opt/apache/bin/php -f /share/Web/gps/gateway.php&

Or make use of screen command in run non-daemon version of your listener in "wirtual" terminal.