【问题标题】:Persistent local domain socket in phpphp中的持久本地域套接字
【发布时间】:2012-01-25 14:40:06
【问题描述】:

我找到的这个问题的答案(例如hereherehere)都涉及pfsockopen(),它似乎适合非本地套接字连接。但是,到目前为止,我编写的代码使用 php 通过本地连接访问 C++ 服务器。我希望这种连接是持久的(顺便说一下,我可以将它用于 Comet)。这是我的非持久版本:

<?php
session_start();

...

if (($sock = socket_create(AF_UNIX, SOCK_STREAM,0)) === false)
{
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
        exit();
}
$sess_id = $_SESSION['sess_id'];
$sock_str = '/tmp/sockdir/' . $sess_id; //The socket is named after the php session, not important
if (socket_connect($sock, $sock_str) === false)
{
        echo "socket_connect() to " . $sock_str . " failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
        socket_close($sock);
        exit();
}

$msg = $_GET['message'];

// ... do things with $msg

socket_close($sock);
?>

我发现,现在我不能简单地将“$sock”保存为 $_SESSION 变量并在每次调用此脚本时简单地访问它。关于如何将其转变为持久连接的任何提示?

【问题讨论】:

  • 这里的问题是请求是有状态的——当请求处于活动状态时,您的 php 应用程序仅在内存中运行。为什么需要持久连接?
  • @tkone 我需要网页来响应服务器生成的消息,而不依赖于特定的客户端请求。这通常是抢手的功能,例如here;这些也称为服务器端事件。
  • 所以您正在寻找 websockets? “页面”需要做什么?这是否意味着页面,因为它已加载到客户端上?您是否考虑过使用 socket.io?目前还没有 PHP 服务器实例,但它可能会对您有所帮助。或者只是研究支持 websockets 或 ajax 长轮询等。
  • @tkone 我知道 WebSockets,但我希望能对我已经编写的内容进行修改。安装 WS 服务器(并让它与我的 C++ 后端接口!)将是一项艰巨的任务。长轮询对我来说似乎太过分了,但 sockets.io 看起来很有趣,谢谢你的提示。我也在研究 Node.js。如果我有任何地方,我会保持更新。
  • 你总是在最后关闭:socket_close($sock);。可能这是造成您的问题?

标签: php javascript sockets comet persistent


【解决方案1】:

正如您提供的链接所指出的,php 不是一种持久性语言,并且无法跨会话(即页面加载)保持持久性。您可以通过将第二个 php 脚本作为守护进程运行来创建中间地带,并让您的主脚本(即用户点击的那个)连接到该脚本(是的 - 通过套接字......)并从中获取数据。

如果您要这样做,并且想避免 Web Sockets 的麻烦,请尝试新的 HTML5 EventStream API,因为它为您提供了两全其美的优势:没有长轮询的 hackyness 的类似 commet 的基础架构或需要专用的 Web Sockets 服务器。

【讨论】:

  • 看起来这是要走的路,虽然创建守护进程不是我以前做过的事情。我找到了教程herehere,如果你知道更好的资源,请告诉我。此外,我还不清楚stream.php--我认为是守护进程--实际上应该在var source = new EventSource('stream.php'); 中工作,我还不太清楚,任何进一步的见解也将不胜感激。
  • 您可能想针对 daemon 和 evepntstream 的内容提出其他问题。随意链接到他们,以便我们看看。感谢您的赏金!
【解决方案2】:

如果需要保持连接打开,则需要保持 PHP 脚本打开。通常 PHP 只是在脚本运行后被调用然后关闭(CGI、CLI),或者它是一种混合体(Apache 中的 mod_php、FCGI),有时 PHP 解释器会在脚本完成后保留在内存中(所以从该进程的操作系统仍将保留为套接字句柄)。

但是,这永远不会保存。相反,您需要使 PHP 成为可以将 PHP 脚本保存在内存中的守护程序。一个现有的解决方案是Appserver-In-PHP。它会将您的代码保留在内存中,直到您重新启动服务器。像代码一样,您也可以在请求之间保留变量,例如一个连接句柄。

【讨论】:

  • 我大体上同意这一点,根据我的经验,人们在长时间运行 PHP 脚本时会有不同的结果。在许多情况下,内存泄漏很难克服 b/c PHP 在设计时考虑了构建/拆卸方法。也就是说,我已经看到并听说过成功的长时间运行的 PHP 脚本 YMMV,但在这种情况下它是最好的方法。如果 PHP 正在泄漏内存,是时候考虑使用 Java 或 C。
  • 如果 PHP 泄漏内存,请检查您的代码是否存在任何缺陷。可以说,您也可以在 C 或 Java 中编写泄漏内存的代码。只是注意到。
猜你喜欢
  • 1970-01-01
  • 2012-01-22
  • 1970-01-01
  • 2012-12-25
  • 1970-01-01
  • 2019-10-11
  • 1970-01-01
  • 2012-06-20
  • 1970-01-01
相关资源
最近更新 更多