用于GCM和MySQL访问的PHP套接字是否需要多线程


Is Multithreading needed for a PHP Socket for GCM and MySQL Access

tl;dr:保持 PHP 套接字被 MySQL 操作解锁的最佳方法是什么?

基本目标:让 PHP+JAXL (XMPP) 套接字通过与 Google CCS GCM 服务器的持久 TCP 连接进行侦听、读取和写入。这是使用此代码完成的。

  • 现在我需要在不阻塞套接字的情况下处理数据(主要是 MySQL)。

我想到了什么:

1:在两个不同的 PHP 线程中建立套接字和数据库连接。通信可以通过JobQueues进行。我发现的基于Geaman,Resque,BeanStalkD的实现。但是,这些工作主要使用主线程和工作线程,因此没有双向通信。

2:将基本队列实现为全局队列?变量,从数据库线程读取作业,并将它们放回另一个队列中。(不知道这是否可能)

3:分叉子进程,如此处建议。然后,每次分叉时我都必须打开一个数据库连接,我认为我可以以某种方式避免这种情况。另外,如何从孩子调用 send()?

硬质零件:

1:需要双向通信:DB 线程必须将结果发送到套接字

2:

应该在共享主机上工作,例如没有Gearman,Redis安装。 另外:没有PHP技能

我在问什么?

  • 需要什么才能不阻塞套接字,什么不需要?

  • 哪种方法适合我的需求,尤其是当我的数据库线程必须将作业分配给套接字("发送 xy")时?

  • 我在这里理解错了什么?

如您所见,我缺乏基本的了解,非常感谢任何指导。多谢。

条条大路通罗马,但也许使用 React PHP 是适合您的解决方案。

它是一个事件驱动的、非阻塞的 PHP I/O 库。它可以满足您的要求,而且您不必深入研究细节即可完成工作。

虽然可以使用 MySQLi 编写异步查询,但不能在同一个 *_select() 调用中将其与网络资源捆绑在一起。但是,您可以(在同一脚本中)轮询异步查询。只需在 socket_select() 中设置一个短暂的超时,并在同一循环中添加对任何已完成的 mysql 查询的检查。像...

$wait=0;
while (true) {
    if (socket_select($netread, $netwrite, $netexcept
        , 0, $wait)) {
        // =...handle socket stuff
        $wait=200;
    }
    if (mysqli_poll($dbread, $dberror, $dbreject
         , 0, 0)) {
       //...handle mysql stuff
       $wait=0;
    }
}

(将等待设置为非零值可防止进程在不执行任何操作时消耗所有 CPU)或者,您可以使用 SIGALARM 来触发轮询。

看看这个版本的 dnode for PHP:

https://github.com/bergie/dnode-php

有助于使过程进行沟通