这就是我自己发现的。
一般
正如 Venkat 所写,您可以用纯 PHP 编写一个简单的侦听器。你只需要通过 SSH 运行它,在 CLI SAPI 模式下的 PHP 中,而不是通过浏览器,因为它会在大约 3-5 分钟后超时失败。
要在 CLI 模式下运行,您需要知道 PHP 的完整路径,并且必须使用正确的开关调用它。例如:
/mnt/ext/opt/apache/bin/php -f /share/Web/projects/gps/gateway.php
PHP CLI 不使用stdout 代替echo(不知道它使用什么)。因此,将任何 echo 替换为将值存储到文件或数据库中,以查看侦听器工作的实际效果。
您可能需要使用set_time_limit(0) 函数来实现无休止、不间断的执行;但据报道(请参阅用户贡献的注释here),对于 CLI SAPI,它被硬编码为 0,因此可能不是强制性的。
在 CLI 模式下运行脚本后,您可以使用 Ctrl+C 将其中断。
监听器示例
这是一个listner的例子,它删除所有内容,它接收到同一目录中的'drop.txt'文件,其中放置了脚本文件:
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);
}
注意事项:
此脚本使用无限循环,因此运行后中断它的唯一方法是按Ctrl+C。
在 socket_bind 中使用 0.0.0.0 IP 地址来监听所有源(IP 地址)或 127.0.0.1 将其限制为仅本地主机。
仔细选择 socket_recvfrom 中的第三个参数——将接收的最大字节数——以确保您等待的数据不会被截断。
你必须使用文件的完整路径,你正在使用——这就是为什么在代码中有$file = './dump.txt',而不是$file = 'dump.txt'。没有完整路径,只能通过浏览器运行。
使用数据库
如果您决定将接收到的 UDP 数据包放入数据库并为此选择 SQLite,您不仅需要提供数据库文件的完整路径,还需要提供绝对路径!所以:
$dbhandle = new SQLiteDatabase('/share/Web/projects/gps/data.db');
不是:
$dbhandle = new SQLiteDatabase('data.db');
甚至:
$dbhandle = new SQLiteDatabase('./data.db');
在某些系统上,第二次和第三次尝试会失败(取决于 PHP 配置),在这种情况下,您会看到警告,即在数据库文件中没有您要查找的此类表。
注销问题修复
如果您无法直接访问将在其上运行该侦听器的计算机,并且您通过 SSH 进行连接,请记住,一旦您注销,您的侦听器可能会被关闭。
要解决此问题,您必须以守护程序模式运行 PHP 脚本(通过在末尾添加 &):
/mnt/ext/opt/apache/bin/php -f /share/Web/gps/gateway.php&
或使用screen 命令在“虚拟”终端中运行非守护程序版本的监听器。