Gracias de nuevo.
¿qué planteamiento me recomiendas?
Estoy leyendo sobre montar un node.js en lugar de hacer el socket con php.... ¿Qué opinas? ¿Otra forma?
De todos modos... sitúo mi código para ver si aclaro la situación ....
Archivo php que ejecuta la aplicación Ruby para conectar al socket y esperar respuesta (recupera el xml enviado por Ruby, su cabecera http y se queda esperando. Funciona ok.. salvo la respuesta, que este mismo php devuelve a Ruby. Ahora mismo, es al php al que no le llega respuesta, por tanto envía a Ruby "vacío"):
Código PHP:
<?php
//Lectura de Headers
$headers = apache_request_headers();
$cabeceras = '';
foreach ($headers as $header => $value) {
$cabeceras = $cabeceras . " $header: $value\n";
}
$handle = fopen("headers.txt", "wb");
fwrite($handle,$cabeceras );
//Carga del xml recibido
$xml = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->preserveWhiteSpace = FALSE;
# Load the request body into XML and check that the result has been parsed into XML
if ($dom->loadXML($xml)){
$texto = '';
$requestDoc = simplexml_load_string($xml);
$valor = $requestDoc->request->getNotifications->lastSeq;
$handle = fopen("bridge.txt", "wb");
fwrite($handle,$valor);
//Conectamos con el socket
$host="172.26.10.21";
$socket=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
$puerto=4545;
$conexion=socket_connect($socket,$host,$puerto);
$tamano=1024;
if($conexion){
$buffer = $valor;
$salida='';
socket_write($socket,$buffer);
while($salida=socket_read($socket,$tamano)){
if ($salida===false){
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);
die("No se pudo crear el socket: [$errorcode] $errormsg");
}else{
echo $salida;
}
$handle = fopen("salidaabridge.txt", "wb");
fwrite($handle,$salida);
}
}else{
echo "\n La conexion TCP no se a podido realizar, puerto: ".$puerto;
}
socket_close($socket); //cierra el recurso socket dado por $socket
} else {
http_response_code(501);
}
?>
Archivo socket.php:
Es el php que genera el socket. Parto de un ejemplo de chat después de dar muchas vueltas.
Recibir recibe bien los xml o datos que le enviemos, pero no consigo dar salida a las respuestas... Ahora mismo esas respuestas deberían ser lo que llega del "otro cliente".
He comentado partes que creo que no me hacen falta como el handshaking....
Código PHP:
<?php
set_time_limit(0);
error_reporting(E_ALL);
$host = '0'; //host
$port = 4545; //port
$null = NULL; //null var
//Create TCP/IP sream socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//reuseable port
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
//bind socket to specified host
socket_bind($socket, 0, $port);
//listen to port
socket_listen($socket);
//create & add listning socket to the list
$clients = array($socket);
//start endless loop, so that our script doesn't stop
while(true){
//manage multipal connections
$changed = $clients;
//returns the socket resources in $changed array
$write = NULL;
$except = NULL;
socket_select($changed, $write, $except, 0, 10);
//check for new socket
if (in_array($socket, $changed)) {
$socket_new = socket_accept($socket); //accpet new socket
$clients[] = $socket_new; //add socket to client array
$header = socket_read($socket_new, 1024); //read data sent by the socket
perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake
socket_getpeername($socket_new, $ip, $port); //get ip address of connected socket
echo "Cliente $ip esta conectado.... $port \n\n";
echo "Recibido: $header \n\n";
//$response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' connected'))); //prepare json data
//echo $response;
$response = "prueba";
//echo "Enviado: " . $header . "\n\n";
//make room for new socket
$found_socket = array_search($socket, $changed);
unset($changed[$found_socket]);
//@socket_write($socket_new,$header,strlen($header));
//send_message("ok"); //notify all users about new connection
}
//loop through all connected sockets
foreach ($changed as $changed_socket) {
//check for any incomming data
while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)
{
$received_text = $buf; //unmask data
//$received_text = unmask($buf);
//$tst_msg = json_decode($received_text); //json decode
//$user_name = $tst_msg->name; //sender name
//$user_message = $tst_msg->message; //message text
//$user_color = $tst_msg->color; //color
//prepare data to be sent to client
//$response_text = mask(json_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message, 'color'=>$user_color)));
$response_text = "prueba1";
socket_sendmsg($changed_socket, $response_text);
//send_message($response_text); //send data
//send_message("datosRet"); //send data
break 2; //exist this loop
}
$buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ);
if ($buf === false) { // check disconnected client
// remove client for $clients array
$found_socket = array_search($changed_socket, $clients);
socket_getpeername($changed_socket, $ip);
unset($clients[$found_socket]);
//echo "Desconectado: " . $ip . "\r\n";
//notify all users about disconnected connection
//$response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' disconnected')));
$response = "Prueba2";
socket_sendmsg($changed_socket, $response);
//send_message($response);
}
}
}
socket_close($socket);
function send_message($msg)
{
global $clients;
foreach($clients as $changed_socket)
{
@socket_write($changed_socket,$msg,strlen($msg));
}
return true;
}
//Unmask incoming framed message
function unmask($text) {
$length = ord($text[1]) & 127;
if($length == 126) {
$masks = substr($text, 4, 4);
$data = substr($text, 8);
}
elseif($length == 127) {
$masks = substr($text, 10, 4);
$data = substr($text, 14);
}
else {
$masks = substr($text, 2, 4);
$data = substr($text, 6);
}
$text = "";
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i] ^ $masks[$i%4];
}
return $text;
}
//Encode message for transfer to client.
function mask($text)
{
$b1 = 0x80 | (0x1 & 0x0f);
$length = strlen($text);
if($length <= 125)
$header = pack('CC', $b1, $length);
elseif($length > 125 && $length < 65536)
$header = pack('CCn', $b1, 126, $length);
elseif($length >= 65536)
$header = pack('CCNN', $b1, 127, $length);
return $header.$text;
}
//handshake new client.
function perform_handshaking($receved_header,$client_conn, $host, $port)
{
$headers = array();
//$lines = preg_split("/\r\n/", $receved_header);
//foreach($lines as $line)
//{
// $line = chop($line);
// if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))
// {
// $headers[$matches[1]] = $matches[2];
// }
//}
//$secKey = $headers['Sec-WebSocket-Key'];
//$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
//hand shaking header
//$upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
//"Upgrade: websocket\r\n" .
//"Connection: Upgrade\r\n" .
//"WebSocket-Origin: $host\r\n" .
//"WebSocket-Location: ws://$host:$port/demo/shout.php\r\n".
//"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
$upgrade = $receved_header;
socket_write($client_conn,$upgrade,strlen($upgrade));
}
?>
Espero que pueda servir esta parrafada.. jaja...
Muchísimas gracias de nuevo...