【问题标题】:Websockets for pushing events from server to client in PHP用于在 PHP 中将事件从服务器推送到客户端的 Websocket
【发布时间】:2014-02-04 04:42:14
【问题描述】:

我有一个场景,当服务器上的某些事情发生变化时,必须更新网络客户端。为此,我在服务器端要么

  • 主动收集更改的无限循环
  • 一个回调,一个事件监听器,通过一个事件循环连接到另一个系统/框架/类

当这个机制发现变化或接收到一个事件时,它需要通过 websocket 将它传递给 webclient。

虽然这很简单,例如在 Java 中,由于事件循环(线程),您有了“正在运行的应用程序”的概念,但这并不能很好地映射到 PHP。 PHP 旨在服务于 HTTP 请求,本质上是无状态的。当一个请求进来时,一个 PHP 脚本被执行,做一些事情并呈现一个响应,然后消失在空虚中。

如何让服务器端 PHP 进程运行以侦听事件并为 web 客户端打开与它的 websocket 连接提供方法?很像一个独立启动的线程,事件监听器可以订阅?

我能想到的可能解决方案:

场景 A:PHP 线程(pthreads)

如果使用 PHP 线程,它是这样工作的吗?

  • Webclient A 发出请求
  • 在服务器端启动一个新线程来保持 websocket 连接并进行监听工作
  • “正常”响应/请求线程(产生事件监听线程的线程)在发回响应后结束
  • 客户端和服务器现在已连接。客户端 A 现在有自己的线程在服务器上运行
  • 当 webclient B 发出请求时,同样会专门针对他/她发生,从而创建一个新线程,可能与 A 的第一个线程执行相同的工作

场景 B:CRON

为了模拟事件循环,可以设置 CRON 作业以在特定时间间隔运行 PHP 脚本。虽然这完成了收集客户感兴趣的事件的工作,但您如何获得 websocket 端点?由于这个 PHP 脚本独立于 Web 运行,您如何将它加入到打开的 (?) 套接字中?必须有人控制它们...

如果 PHP 由于其“脚本设计”而不适合 websockets,那么有什么好的替代方案?

【问题讨论】:

  • 你考虑过使用 node.js 吗?
  • php 不是多线程语言...
  • @MarcB:正确,但是有pthread extension
  • @MarcB 是的,是...
  • Pthreads 令人难以置信,但我无法让它与 websockets 一起工作(特别是棘轮)。我可以将 mysql 资源传递给线程工作者,但不能传递给 websocket 资源。除了资源停止存在(无论我是否将资源传递给线程)之外,我还收到了无法序列化关闭消息。实际上,我将把它作为一个问题发布。

标签: php multithreading events architecture websocket


【解决方案1】:

Ratchet 是一个很棒的 php websocket 服务器:http://socketo.me/

这就是我的工作:

$loop   = React\EventLoop\Factory::create();
$pusher = new MyApp\Pusher();

// run ratchet as a daemon @ 0.5 second intervals
$loop->addPeriodicTimer(0.50, function() use($pusher){
    //$thread = new AsyncThread\AsyncThread($pusher->clients); // Really wished this worked, but everytime i send a websocket resource to a thread the thread throws a fatal error if i attempt to bind the data and even if I dont the resource disappears /sigh
    $pusher->load(); // so I just call this function which basically handles each client one after the other as opposed to simultaneously via threads.
});

$webSock = new React\Socket\Server($loop);

if ($loop instanceof \React\EventLoop\LibEventLoop) {
    echo "\n HAS LibEvent"; // apparently performance is better with the libevent php extension callback installed; I haven't really noticed a significant difference
}

$webSock->listen(8080, '0.0.0.0'); // Binding to 0.0.0.0 means remotes can connect
$webServer = new Ratchet\Server\IoServer(
    new Ratchet\Http\HttpServer(
            new Ratchet\WebSocket\WsServer($pusher)
    ),
    $webSock
);

$loop->run();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    • 2017-09-15
    相关资源
    最近更新 更多