-
Notifications
You must be signed in to change notification settings - Fork 1k
PHP
In order to run applications over a WebSocket written in PHP you'll need to be using the (CLI) compiler.
To find out what PHP version your command line interface defaults to use
php -v
If your compiler defaulted to something like PHP-fastcgi, ect. you'll need to find the path to the CLI in your system.
In my particular build, I had to add #!/usr/local/bin/php
in a shebang at the top of my script.
This allows you to not use the
# websocketd --port=8080 Socket.php
rather than
# websocketd --port=8080 php Socket.php
This is a simple echo server as well as a fifo named pipe implementation. If user A sends a message to user B I can look up what FIFO may be present if user B is online. I store IP addresses in the database so I'll link that with the user id. Then store the file as
$fifo = $_SESSION['user_id'] .'.fifo'
if the file_exist()
you can send the messages directly after posting to the database (successfully) to the fifo in a json array (or however you choose to implement).
Happy programming
- Richard Miles
This example will echo a message sent from a WS client back to the WS client, and will also broadcast the same message to any other connected WS client.
Socket.php
#!/usr/local/bin/php
<?php
# https://www.leaseweb.com/labs/2013/08/catching-signals-in-php-scripts/
pcntl_async_signals(true);
pcntl_signal(SIGINT, 'signalHandler'); // Interrupted ( Ctrl-C is pressed, or `kill -SIGINT <pid>` occurred)
$FIFODIR=__DIR__;
$unique_id = $_SERVER['UNIQUE_ID'];
$fifoPath = $FIFODIR . '/' . $unique_id . '.fifo';
print $fifoPath;
if (!file_exists( $fifoPath )) shell_exec("mkfifo " . $fifoPath);
if (pcntl_fork() == 0)
{ // child - create writer on fifo
$file = fopen($fifoPath,"w");
sleep(1);
exit(0);
} else {
$fifoFile = fopen( $fifoPath, 'r' ); // the writer above allows this fopen to unblock.
stream_set_blocking($fifoFile, false); // when using stream_select to block, all handles should be set to non blocking.
}
$stdin = fopen('php://stdin', 'r');
echo "COMMUNICATION STARTED\n ID :: " . $unique_id . "\n\n";
$running = true;
while($running) {
// build up $readers array for every stream_select call since stream_select will remove any unchanged fd's from the lists.
$readers = array($fifoFile, $stdin);
if (($stream = stream_select( $readers, $writers, $except, 1)) === false) {
print "A stream error occurred\n";
break;
} else {
foreach ($readers as $input => $fd) {
if ($fd == $stdin) {
$line = fgets($stdin);
if ($line === false) {
// EOF
$running = false;
break;
}
// TODO - search in app
print "You sent :: $line \n";
// send message to all other connected WS clients
if ($dh = opendir($FIFODIR)) {
while (($file = readdir($dh)) !== false) {
if (substr($file, -5) == '.fifo') {
$handle = fopen($FIFODIR . '/' . $file, "w");
fwrite($handle, $unique_id . ' says ');
fwrite($handle, $line);
fclose($handle);
}
}
closedir($dh);
}
} elseif ($fd == $fifoFile) {
$data = fread( $fifoFile, $bytes = 124 );
if (!empty( $data )) print "App Sent :: " . $data . "\n";
}
}
}
}
@fclose($stdin);
@fclose($fifoFile);
@unlink($fifoPath);
// clients will not see this when they initiate the disconnect.
print "Safe Exit \n\n";
exit(0);
function signalHandler($signal)
{
print "Signal :: $signal\n";
global $running;
$running = false;
// stream_select becomes unblocked after this signalHandler runs
}
The websocketd user guide is a publicly editable wiki. Please contribute!
Getting Started
Reference
Language specific
Advanced: Internals
Spanish Websocket Wiki
Primeros pasos
Referencia
Lenguajes
Avanzado