Foros del Web » Programando para Internet » PHP »

Duda sobre planteamiento de desarrollo

Estas en el tema de Duda sobre planteamiento de desarrollo en el foro de PHP en Foros del Web. Hola. Estoy liado con un proyecto, que tras muchas pruebas, no consigo sacarlo para adelante, y me lleva a plantearme si el análisis y como ...
  #1 (permalink)  
Antiguo 28/02/2014, 15:59
 
Fecha de Ingreso: agosto-2003
Mensajes: 324
Antigüedad: 20 años, 8 meses
Puntos: 1
Duda sobre planteamiento de desarrollo

Hola.
Estoy liado con un proyecto, que tras muchas pruebas, no consigo sacarlo para adelante, y me lleva a plantearme si el análisis y como lo afronto es el correcto.
De ahí que os pida ayuda y sugerencias.
Os planteo la situación:

Tengo que comunicar 2 aplicaciones.
Una de ellas es en entorno web, tipo CMS, desarrollada con .net y asp, pero tengo pocas posibilidades de modificar su código. Como mucho, generar frames que contengan archivos html,php... que son los que puedo usar para comunicarme con otras aplicaciones, usando jquery o el propio php.

Por otro lado, hay una aplicación, de al que se poco, sólo que está desarrollada con Ruby.

La comunicación consiste en que la primera, el CMS, actúa como servidor, y debe integrar un servicio de Long Polling, de forma que la otra, la de Ruby, actúa como cliente, conectándose al servicio Long Polling, a la esperando a que el CMS le mande alguna notificación, y actuar en consecuencia.

Por ahora lo he montado con un socket en php, que me está ejecutando bien.
La aplicación de Ruby (Cliente) se conecta mediante la llamada de un php (conex.php) gestionado por el CMS, al cual le envía un xml , vía post, y ese php se conecta con el socket, pasándole los datos. En el socket visualizo dichos datos. Se queda a la espera.

Cuando en el CMS se dispara algún evento , un click de un botón por ejemplo, se ejecuta el archivo que hemos metido en uno de los frames (envío.html), el cual con ajax, se conecta al socket anterior y le envía un xml vía post. La información llega y se visualiza en el socket.

He montado el socket como una "especie de chat", de forma que pretendo que al conectarse desde el CMS, y al estar a la escucha la parte Cliente, pretendo que el socket le envíe los datos recibidos del xml por parte del CMS hacia el Cliente. Como si fuera un mensaje del usuario 2 al usuario 1 en un chat.... Para que la aplicación de Ruby, la cliente, recepcione dicho xml y ejecute en consecuencia.

Por otra parte, como envié el xml del CMS con ajax, y se queda a la espera de respuesta... pues obtener datos de respuesta por parte del Cliente... como si fuera una respuesta del usuario 1 al usuario 2 en el "chat".

Bien... los envíos los tengo.. pero no consigo obtener las respuestas del socket a cada uno de los clientes.

Estoy dándole vueltas y como no consigo solucionarlo... pues me planteo si está bien pensado el sistema y las tecnologías o no.

He pensado cambiar y montar un node.js como socket, y seguir manteniendo los envíos/recepción con archivos intermedios en php que serán los que se encarguen de mandar/recibir del node.js...

¿Qué opináis?
¿Algún consejo?
¿Ejemplo?

Espero me hayáis entendido... si hace falta aclarar algo...

Muchas gracias....
  #2 (permalink)  
Antiguo 02/03/2014, 05:23
lolainas
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Duda sobre planteamiento de desarrollo

Hola compi, vamos a ver, según entiendo:

Aplicación CMS
- Recibe solicitudes desde Aplicación Ruby
- Te permite escribir módulos o frames que respondan a esas solicitudes

Aplicación Ruby
- No tienes control sobre ella
- Según entiendo será un usuario de esta aplicación el que con (por ejemplo) un click de ratón envíe una solicitud a la aplicación CMS.

Viendo este panorama, creo que no hace falta ningún intermediario, simplemente que tú escribas dichos módulos o frames que sean capaces de enviar respuestas a las solicitudes del usuario de la aplicación Ruby, es decir, el "intermediario" sería ese usuario que necesita una respuesta.

Espero haberte entendido y haberme hecho entender. Saludos.
  #3 (permalink)  
Antiguo 02/03/2014, 06:06
 
Fecha de Ingreso: agosto-2003
Mensajes: 324
Antigüedad: 20 años, 8 meses
Puntos: 1
Respuesta: Duda sobre planteamiento de desarrollo

Gracias por la respuesta.
Básicamente es así, pero con algunos matices.
El cms está construido de forma que puedo modificar poco su estructura. Éste además, luego cuando recibe una respuesta, guarda datos en un sql server.
Con el frame que insertó que contendrá un HTML, lo que hago es meter un código jquery y alex que se encargara de hacer el envío y recepción de los datos al socket.

La aplicación ruby realmente lo que hace es mandar un xml al socket y permanecer a la espera (long polling) de que llegue un xml, en este caso desde el envío ajax del frame del cms. Cuando llega ese segundo xml, disparar cómo respuesta al xml de la aplicación de ruby, un xml según los datos que ha enviado el cms....

Ruby interactúa según ese xml, procesa y vuelve a mandar información al socket, que se la devolvería a la petición ajax que hizo el cms....

A ver si así puedo ayudar a que entiendas el proceso mejor....

He seguido buscando info ,p y lo que veo que conjugue php y jquery más o menos así son ejemplos donde se usa un archivo txt como almacén y respuesta de todos los datos... Ese txt actuaría como un servicio "chat" donde los otros se conectan mediante un bucle que comprueba si se ha escrito algo nuevo.....

No se.. Cada vez me hago más lío.. Jajaja

Espero me podáis aconsejar,....
Gracias
  #4 (permalink)  
Antiguo 02/03/2014, 07:15
lolainas
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Duda sobre planteamiento de desarrollo

Vale, entonces sí exite el intermediario, porque la aplicación CMS también emite solicitudes a la aplicación Ruby...
Ten en cuenta que ese bucle para comprobar si hay algo nuevo es imposble de implementar en la web ya que una aplicación web está muerta hasta que un usuario le envía una solicitud...
Es decir, a no ser que tu escribas en el navegador: 'app_cms.com/args' esa aplicación no está funcionando... sólo podrías comprobar si hay novedades en el txt invocando la aplicación.

EDITO:
Has descrito el problema de forma clara y la solución que pretendes darle, aunque muy abstracto. Quizás si concretaras un poco más (qué tipo de información pretendes enviar a Ruby y que tipo de respuesta debería emitir) podríamos llegar más rápido a la solución.

Última edición por lolainas; 02/03/2014 a las 07:24
  #5 (permalink)  
Antiguo 02/03/2014, 08:04
 
Fecha de Ingreso: agosto-2003
Mensajes: 324
Antigüedad: 20 años, 8 meses
Puntos: 1
Respuesta: Duda sobre planteamiento de desarrollo

Ok, gracias... intento dar más detalles...

EL CMS es un aplicativo de "construcción" de sitios web, pero que como digo, poco puedo personalizar, salvo la inserción de los iframes que comenté.

En la web, desde el CMS, se carga un formulario con datos recogidos de la bd.
Existirá un botón, que manejaré con jquery desde "mi" iframe... el cual, al pulsarlo, recopila información que tiene el formulario en pantalla, y genera un xml que es el que enviaré vía ajax hacia el "socket" (o lo que sea...)

Mientras... la aplicación Ruby, que no es una aplicación web .. sino una aplicación que se ejecuta de forma autónoma en un ordenador remoto, se conecta a "mi socket" enviando un xml, con datos como el id de envío entre otros... y se queda a "la espera". Es como si envía una pregunta constante preguntando si "hay algo nuevo".

Cuando el xml que envió el CMS vía Ajax llega al socket, ese xml actúa como la respuesta que estaba esperando el xml enviado por la aplicación Ruby. De ahí mi "pensamiento" de darle como forma de chat.

El socket da esa información hacia la aplicación Ruby, en formato xml (junto a cabecera 200 ok, por ejemplo), el cual procesará la aplicación Ruby, ejecuta algo, y devuelve el resultado de dicha operación como otro xml hacia el socket.

El xml que envío el CMS vía ajax está a la espera de respuesta. Como ahora llega un nuevo xml (el de la respuesta a la ejecución de la aplicación Ruby) el socket se lo envía en formato xml como repuesta al envío Ajax.

Y ahi termina el proceso.

La diferencia a un chat es que sólo habrá 2 posibles clientes conectados.. lo que llega/se envía del CMS y lo que llega/envía desde Ruby.

Espero vuestros comentarios...

Muchas gracias
  #6 (permalink)  
Antiguo 02/03/2014, 15:34
lolainas
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Duda sobre planteamiento de desarrollo

Cita:
Iniciado por AJDC Ver Mensaje
Ok, gracias... intento dar más detalles...

EL CMS es un aplicativo de "construcción" de sitios web, pero que como digo, poco puedo personalizar, salvo la inserción de los iframes que comenté.

En la web, desde el CMS, se carga un formulario con datos recogidos de la bd.
Existirá un botón, que manejaré con jquery desde "mi" iframe... el cual, al pulsarlo, recopila información que tiene el formulario en pantalla, y genera un xml que es el que enviaré vía ajax hacia el "socket" (o lo que sea...)

1. El CMS envía info al socket desde el formulario

Mientras... la aplicación Ruby, que no es una aplicación web .. sino una aplicación que se ejecuta de forma autónoma en un ordenador remoto, se conecta a "mi socket" enviando un xml, con datos como el id de envío entre otros... y se queda a "la espera". Es como si envía una pregunta constante preguntando si "hay algo nuevo".

2. Aplicación Ruby pregunta y el socket le dice SÍ, TENGO ALGO, TOMA...

Cuando el xml que envió el CMS vía Ajax llega al socket, ese xml actúa como la respuesta que estaba esperando el xml enviado por la aplicación Ruby. De ahí mi "pensamiento" de darle como forma de chat.

El socket da esa información hacia la aplicación Ruby, en formato xml (junto a cabecera 200 ok, por ejemplo), el cual procesará la aplicación Ruby, ejecuta algo, y devuelve el resultado de dicha operación como otro xml hacia el socket.

El xml que envío el CMS vía ajax está a la espera de respuesta. Como ahora llega un nuevo xml (el de la respuesta a la ejecución de la aplicación Ruby) el socket se lo envía en formato xml como repuesta al envío Ajax.

El CMS es una aplicación Web por lo tanto está dormida hasta que la invocas, así que este último paso creo que es el que falla y donde la Aplicación Ruby una vez procesados los datos recibidos en una variable (por ejemplo) salida, debe enviarsela directamente al CMS sin intermediario. Ya que el CMS como aplicación Web que es no puede estar preguntando constantemente si hay algo nuevo...

Y ahi termina el proceso.

La diferencia a un chat es que sólo habrá 2 posibles clientes conectados.. lo que llega/se envía del CMS y lo que llega/envía desde Ruby.

Espero vuestros comentarios...

Muchas gracias
  #7 (permalink)  
Antiguo 02/03/2014, 16:06
 
Fecha de Ingreso: agosto-2003
Mensajes: 324
Antigüedad: 20 años, 8 meses
Puntos: 1
Respuesta: Duda sobre planteamiento de desarrollo

Gracias por la respuesta.
Realmente el primero que interactúa es la aplicación Ruby que envía y se mantiene a la espera.... Pero básicamente es como recalcas.
Desde el cms el envío lo hago con ajax y según el inspector del navegador se queda a la espera de la respuesta.
Mi problema por ahora de todas las pruebas es que no consigo que bien el ajax o bien ruby obtengan la respuesta del socket. Creo que el problema lo tengo en él.

¿Alguna sugerencia de cómo crear la interactuación?
¿Sigo con el mismo planteamiento?
¿Algún ejemplo, tutorial.... O lo que sea?

Muchas gracias
  #8 (permalink)  
Antiguo 02/03/2014, 16:14
lolainas
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Duda sobre planteamiento de desarrollo

Por lo que te digo, porque ajax si no lo ejecutas no se ejecuta por sí sólo, debes invocar la web o un botón suyo para ejecutar el ajax, no va a recoger información del socket por sí sola, si no se lo indicas.
Sí, creo que deberías cambiar el planteamiento, como te he dicho, el único que puede escuchar constantemente ya que vive en un proceso, es Ruby...

A una mala pega aquí el socket ...
  #9 (permalink)  
Antiguo 03/03/2014, 02:02
 
Fecha de Ingreso: agosto-2003
Mensajes: 324
Antigüedad: 20 años, 8 meses
Puntos: 1
Respuesta: Duda sobre planteamiento de desarrollo

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_INETSOCK_STREAMSOL_TCP);
//reuseable port
socket_set_option($socketSOL_SOCKETSO_REUSEADDR1);
//bind socket to specified host
socket_bind($socket0$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$except010);

    
//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_new1024); //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$buf10240) >= 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_socket1024PHP_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($text44);
        
$data substr($text8);
    }
    elseif(
$length == 127) {
        
$masks substr($text104);
        
$data substr($text14);
    }
    else {
        
$masks substr($text24);
        
$data substr($text6);
    }
    
$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'$b1126$length);
    elseif(
$length >= 65536)
        
$header pack('CCNN'$b1127$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...

Etiquetas: desarrollo, html
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 12:46.