Ok - I've had a minor breakthrough with this. I decided that the two scripts, which I think of as shopkeeper and customer should act like this when they want to talk.
Shopkeeper opens up shop (i.e. creates a socket) but then has to SHOUT his address at his customer to tell him he's open (and on what port)
It's the shouting bit I'm wary of - because within the shopkeeper script it triggers the script on the other site with fsockopen, then closes that and then does the rest of the chatting. I've got the fear that the fsocket way may be really bad practise.
Here are the scripts (which do work) but has anybody got a better suggestion for the whole of this - or even just a safer way of triggering the customer
shopkeeper.php
<?php
// Set time limit low because I'm scared
$timeLimit=5;
set_time_limit ($timeLimit+1);
$startTime=getmicrotime();
// using a port of zero means that we get a two times fresh one when binding
$address = $_SERVER['HTTP_HOST'];
$port = 0;
// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
// Bind the socket to an address/port
socket_bind($sock, $address, $port) or die('Could not bind to address');
// find our socket
socket_getsockname ( $sock, $checkAddress, $port );
echo "My Check Address: $checkAddress and port: $port<br>";
// Start listening for connections
socket_listen($sock);
//instigate my customer to talk to me
$url=$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF'])."/customer.php?port=$port&addr=$checkAddress&exit=true";
echo $url."\n";
$res = trigger_url($url);
/* talk to the customer - NOTE socket_accept WAITS */
$client = socket_accept($sock);
// just guff out who the client is for fun
socket_getpeername ( $client, $pnAddr, $pnPort);
echo "Peer's Address: $pnAddr and port: $pnPort<br>";
while ( getmicrotime() - $startTime < $timeLimit )
{
// Read the input from the client – 1024 bytes
$output = socket_read($client, 1024);
$return="Mr. Shop says: $output";
echo $return."<br>\n";
// Display output back to client
socket_write($client, $return.chr(0) );
if($output == "exit" || $output == "exit\n") break;
} // end while
echo "CLOSING SOCKETS<br>\n";
// Close the client (child) socket
socket_close($client);
// Close the master sockets
socket_close($sock);
echo "SHUTTING DOWN<br>\n";
function getmicrotime()
{
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
// if you DON'T have the Host: bit - NO WORK with subdomains
function trigger_url($url)
{
$url = preg_replace("@^[url]http://@i[/url]", '', $url);
$host = substr($url, 0, strpos($url, '/'));
$uri = strstr($url, '/');
$fp = fsockopen ($host, 80, $errno, $errstr, 10);
$request = "GET $uri HTTP/1.1\r\n".
"User-Agent: MyWebBrowser\r\n".
"Host: $host\r\n".
"Connection: Close\r\n\r\n";
if (!$fp)
return false;
else
{
fputs ($fp, $request);
/* comment this, as only want to trigger the beast
//skips the header, it ends with \r\n
while (!feof($fp) && fgets($fp, 128)!="\r\n" );
while (!feof($fp))
{
$data=fgets ($fp,128);
echo $data;
}*/
}
fclose ($fp);
return true;
}
?>
customer.php
<?php
$port=@$_GET['port'];
$addr=@$_GET['addr'];
//socket to shopkeeper
$fp=fsockopen( $addr, $port, $errno, $errstr, 5 );
if( !$fp )
{
echo "No Socket: $errstr<br><br>$errno";
exit;
}
// gentle banter ensues
fputs($fp, "Hello shoppy");
echo '<br>'.get_socket_response($fp);
fputs($fp, "I'd like some spuds, please");
echo '<br>'.get_socket_response($fp);
fputs($fp, "I saw your Judith fingering the till earlier");
echo '<br>'.get_socket_response($fp);
if( @$_REQUEST['exit'] )
{ echo "Ok - time to go home<br>";
fputs($fp, "exit");
echo get_socket_response($fp);
}
function get_socket_response($fp)
{
stream_set_timeout($fp,2);
$str=fread($fp,1);
$bytes_left = socket_get_status($fp);
$toRead=$bytes_left['unread_bytes'];
if ($toRead > 0)
{
return $str.fread($fp, $toRead);
}
return $str;
}
?>
And that's me waiting,
D