php - 如何在没有fork的情况下在不同函数甚至不同进程之间使用PHP中的命名管道?

标签 php named-pipes blocking

我想编写一个 Ajax Web 应用程序,具体来说是一个游戏。两个 Web 客户端必须通过 PHP 服务器相互通信。我解决这个问题的方法是在客户端和服务器以及服务器和客户端之间使用 Ajax。每个客户端使用 Ajax 创建一个单独的服务器进程。我希望这两个服务器进程通过 MySQL 和命名管道进行通信。我需要命名管道来立即响应整个应用程序。

我不能使用一个服务器进程,它首先创建一个管道,然后 fork 成两个使用管道的进程。当 Web 浏览器发送请求时,Web 应用程序创建服务器进程。所以,我需要命名管道,其中每个进程只知道命名管道的文件名。他们不能交换文件句柄(至少我不知道如何)。

我的问题是 PHP 方式中的命名管道确实可以工作,只要它们是
在同一函数中使用:

public function writeAndReadPipe_test(){
    $pipeA = fopen("testpipe",'r+');
    fwrite($pipeA, 'ABCD');

    $pipeB = fopen("testpipe",'r+');
    $content = fread($pipeB, 4);
    echo "[" . $content . "]<br>\n";
}

public function testingPipes_same_function(){
    posix_mkfifo("testpipe", 0777);
    $this->writeAndReadPipe_test();
}

但是,当我使用不同的功能时, fread($pipeB, 4) 命令阻止整个应用程序:
public function writePipe_test(){
    $pipeA = fopen("testpipe",'r+');
    fwrite($pipeA, 'ABCD');
}

public function readPipe_test(){
    $pipeB = fopen("testpipe",'r+');
    $content = fread($pipeB, 4);
    echo "[" . $content . "]<br>\n";
}

public function testingPipes_different_functions(){
    posix_mkfifo("testpipe", 0777);
    $this->writePipe_test();
    $this->readPipe_test();
}

有人知道为什么吗?我该怎么做才能让它在第一步中的不同功能之间工作?在第二步中,它甚至应该在不同的进程之间工作!我发现当作者在读者阅读之前关闭管道时我也遇到了问题
它。我想该函数在结束时会自动关闭它,但这只是一个猜测。

如果PHP方式不行,我打算让PHP打开命令行,生成BASH命令,让执行。只要我的网络服务器在 LAMP 环境中工作,这在任何情况下都应该有效。缺点是它不能在 WAMP 环境中工作。

那么,有人对此有什么想法吗?

附:
我需要阻塞管道让读者等待直到事件被发送。我知道管道可以在非阻塞模式下使用
stream_set_blocking($pipe,false);

左右,但整个想法是在不轮询的情况下仅使用管道来实现,这会唤醒
一旦事件被触发,reader 就会启动。

最佳答案

只是一个简短的声明,我实际上找到了一个很好的解决方案
使用命名管道:

public function createPipe_test(){
    posix_mkfifo("testpipe", 0777);
}

public function writePipe_test($value){
    $pipeA = fopen("testpipe",'w');
    $valueString = number_format($value);
    $valueLen = number_format(strlen($valueString));
    fwrite($pipeA, $valueLen);
    fwrite($pipeA, $valueString);
}

public function readPipe_test(){
    $pipeB = fopen("testpipe",'r');
    $valueLen = fread($pipeB, 1);
    return fread($pipeB, $valueLen);
}

我有两个进程。

如果进程 1 调用 writePipe_test(), 然后它等到进程 2 调用
readPipe_test() 从管道中读取数据。

如果进程 1 调用 readPipe_test(), 然后它等到进程 2 调用
writePipe_test() 将一些东西写入管道。

诀窍是“w”和“r”而不是“r+”。

关于php - 如何在没有fork的情况下在不同函数甚至不同进程之间使用PHP中的命名管道?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14399801/

相关文章:

java套接字编程阻塞对服务器和客户端的读写

php - 我如何创建多个请求获取/发布页面 url

php - 在 PHP 中读取和显示 JSON 对象时遇到问题

C# 套接字与管道

c - 套接字:为什么阻塞 read() 因 ENOTCONN 而失败?

C# - 如何阻止 GUI 或事件

javascript - Yi2 使用 SendFile() 下载文件

php - MySQL Select - 连接所有匹配的表

python - 如何同时分析和流式传输 RaspberryPi 视频

c++ - 在 Linux 中使用命名管道的简单客户端/服务器程序