4

The answers I've found to this question (such as here, here, and here) all involve pfsockopen(), which seems geared to non-local socket connections. However, the code I've written so far uses php to access a C++ server through a local connection. I want this connection to be persistent (so that I can use it for Comet, incidentally). Here's my non-persistent version:

<?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);
?>

Now I can't simply save '$sock' as a $_SESSION variable and simply access it each time this script is called, I've found. Any tips on what I can do to turn this into a persistent connection?

Community
  • 1
  • 1
Matt Phillips
  • 8,691
  • 8
  • 41
  • 72
  • 1
    the problem here is that requests are stateful -- your php app is only running in memory when the request is active. why do you need the connection to be persistant? – tkone Dec 23 '11 at 22:52
  • @tkone I need the webpage to respond to messages generated by the server independent of a specific client request. This is commonly sought-after functionality, e.g. [here](http://en.wikipedia.org/wiki/Comet_%28programming%29); these are also known as Server-Side Events. – Matt Phillips Dec 23 '11 at 23:31
  • So you're looking for websockets? The "page" needs to do something? Does that mean the page, as it's been loaded on a client? Have you looked into using socket.io? There's no PHP server instance for it yet, but it might help you out there. Or just look into supporting websockets or ajax long polling, etc. – tkone Dec 24 '11 at 03:34
  • @tkone I'm aware of WebSockets, but I was hoping for something more along the lines of a modification of what I've already written. Installing a WS server (and getting it to interface with my C++ back end!) would be a huge undertaking. Long polling seems like too much of a hack to me, but sockets.io looks interesting, thanks for the tip. I'm also looking into Node.js. I'll keep the thread updated if I get anywhere. – Matt Phillips Dec 24 '11 at 06:17
  • 1
    You always close at the end: `socket_close($sock);`. Probably this is creating your issue? – hakre Dec 26 '11 at 15:14
  • Have you read this? http://stackoverflow.com/questions/603201/using-comet-with-php – thatwasbrilliant Dec 27 '11 at 06:02
  • @hakre Sorry for any confusion, but I wasn't implying that my could should be persistent. I tried to modify the above in a simple way (including getting rid of `socket_close($sock)` to get a persistent connection but I've failed so far. – Matt Phillips Dec 27 '11 at 18:05

2 Answers2

4

As the links you provided point out, php is not a persistent language and there is no way to have persistence across sessions (i.e. page loads). You can create a middle ground though by running a second php script as a daemon, and have your main script (i.e. the one the user hits) connect to that (yes - over a socket...) and get data from it.

If you were to do that, and want to avoid the hassel of Web Sockets, try the new HTML5 EventStream API, as it gives you the best of both worlds: A commet like infrastructure without the hackyness of long-polling or the need for a dedicated Web Sockets server.

Mbrevda
  • 2,138
  • 2
  • 21
  • 29
  • It looks like this is the way to go, though creating daemons isn't something I've done before. I've found tutorials [here](http://devlog.info/2010/03/07/creating-daemons-in-php/) and [here](http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/), let me know if you know a better resource. Also, how exactly `stream.php`--the daemon, I take it--is actually supposed to work in `var source = new EventSource('stream.php');` is not fully clear to me yet, any further insights there would be appreciated too. – Matt Phillips Dec 30 '11 at 21:19
  • You probably want to open additional questions for the daemon and evepntstream stuff. Feel free to link to them so that we can have a look. Thanks for the bounty! – Mbrevda Dec 31 '11 at 15:41
2

If you need to keep the connection open, you need to keep the PHP script open. Commonly PHP is just invoked and then closed after the script has run (CGI, CLI), or it's a mixture (mod_php in apache, FCGI) in which sometimes the PHP interpreter stays in memory after your script has finished (so everything associated from the OS to that process would still remain as a socket handle).

However this is never save. Instead you need to make PHP a daemon which can keep your PHP scripts in memory. An existing solution for that is Appserver-In-PHP. It will keep your code in memory until you restart the server. Like the code, you can as well preserve variables between requests, e.g. a connection handle.

hakre
  • 178,314
  • 47
  • 389
  • 754
  • I agree with this in general, folks will have mixed results w/ long running PHP scripts in my experience. In many cases memory leaks are hard to overcome b/c PHP was designed with the build-up / tear-down approach in mind. That said I have seen & heard of successful long running PHP scripts, YMMV, but it's the best approach in this case. If PHP is leaking memory it's time to consider Java or C. – quickshiftin Dec 28 '11 at 19:22
  • If PHP leaks memory, check you don't have any flaws in your code. You can write code that leaks memory as well in C or Java, so to say. Just noting. – hakre Dec 28 '11 at 19:31