Comunidad de diseño web y desarrollo en internet online

Manteniendo vivo un socket server en PHP

Citar            
MensajeEscrito el 17 Nov 2011 03:15 pm
Buenas con todos:
Tengo una consulta conrespecto a el tema de sockets en PHP, logro mantener "viva" la conexion gracias a una funcion recursiva:

server.php

Código PHP :

class SocketServer{
   public $host;
    public $port;
   public $closed;
   public $event;
    public function __construct($vhost='127.0.0.1',$vport=2356){
        if(!preg_match("/\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}/",$vhost)){
            trigger_error('Invalid IP address format.',E_USER_ERROR);
        }else{ echo $vhost; }
        if(!is_int($vport)||$vport<1||$vport>65535){
            trigger_error('Invalid TCP port number.',E_USER_ERROR);
        }
        $this->host=$vhost;
        $this->port=$vport;
        $this->connect();
    }
    function connect(){
        set_time_limit(0);
        // create low level socket
        if(!$socket=socket_create(AF_INET,SOCK_STREAM,0)){
            trigger_error('Error creating new socket.',E_USER_ERROR);
        }
        // bind socket to TCP port
        if(!socket_bind($socket,$this->host,$this->port)){
            trigger_error('Error binding socket to TCP port.',E_USER_ERROR);
        }
        // begin listening connections
        if(!socket_listen($socket)){
            trigger_error('Error listening socket connections.',E_USER_ERROR);
        }
        // create communication socket
        if(!$comSocket=socket_accept($socket)){
            trigger_error('Error creating communication socket.',E_USER_ERROR);
        }
        // read socket input
        $socketInput=socket_read($comSocket,1024);
        // convert to uppercase socket input 
        $socketOutput=strtoupper(trim($socketInput))."n";
        // write data back to socket server
        if(!socket_write($comSocket,$socketOutput,strlen($socketOutput))){
            trigger_error('Error writing socket output',E_USER_ERROR);
        }
        // close sockets
        socket_close($comSocket);
      $this->event = $this->closeSocket($socket);
    }
   function closeSocket($sObj) {
      socket_close($sObj);
      return true;
   }
}

$loco =& new SocketServer();
keepAlive();
function keepAlive() {
   global $loco;
   if($loco->event == true) {
      $loco =& new SocketServer();
      keepAlive();
   }
}


y este es:
client.php

Código PHP :

<?php
// check if form was submitted
if(isset($_POST['send'])){
   //include_once('server.php');
    // open client connection to TCP server
    if(!$fp=fsockopen('127.0.0.1',2356,$errstr,$errno,30)){
        trigger_error('Error opening socket',E_USER_ERROR);
    }
    $message=$_POST['message'];
    // write message to socket server
    fputs($fp,$message);
    // get server response
    $ret=fgets($fp,1024);
    // close socket connection
    fclose($fp);
    echo '<h1>You entered the following message in
lowercase :'.$ret.'</h1>';
    exit();
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>TESTING TCP SOCKET SERVER</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-
8859-1" />
</head>
<body>
<h1>Enter your message here</h1>
<form action="<?php echo $_SERVER['PHP_SELF']?>" method="post">
<input type="text" name="message" size="30" /><br />
<input type="submit" name="send" value="Send Value" />
</form>
</body>
</html>


$event en la clase dispara true una vez que la conexion del socket se cierra entonces Keep alive verifica si se "produjo" el evento de cierre y vuelve a crear otro socket y este se mantiene a la espera de datos del cliente, una vez recibido se cierra y keepAlive se ejecuta de nuevo (funcion recursiva).

Ahora dato extra, una vez ejecutas server.php en tu navegador, LO CIERRAS, y puedes enviar con client.php las veces que quieras. Puedo crear otro evento para detenerlo, pero mi pregunta es: Este script puede generar algun daño al servidor?

Por Mr. X-ecutor

96 de clabLevel

1 tutorial

Genero:Masculino  

12/02/2007

firefox
Citar            
MensajeEscrito el 17 Nov 2011 04:03 pm
prueba viendo si sobrecarga los procesos de la maquina. Interesante eso de los sockets en php, supongo que necesitas ahora una libreria para hacer funcionar e soket con javascript

Por Inyaka

Claber

3176 de clabLevel

9 tutoriales
2 articulos

Genero:Masculino   Desarrollador de GAIA

Programador y fotógrafo

chrome
Citar            
MensajeEscrito el 17 Nov 2011 04:17 pm
Si el proceso es recursivo, entonces estás consumiendo más recursos del servidor conforme se dispara cada instancia recursiva. Dado suficiente tiempo es posible que agotes la memoria asignada a PHP.

Por DriverOp

Claber

2510 de clabLevel



 

opera
Citar            
MensajeEscrito el 17 Nov 2011 04:37 pm
los socket no son recursivos, solo dejan abierto el canal para escuchar, por eso lo digo que revise los procesos de la maquina

Por Inyaka

Claber

3176 de clabLevel

9 tutoriales
2 articulos

Genero:Masculino   Desarrollador de GAIA

Programador y fotógrafo

chrome
Citar            
MensajeEscrito el 17 Nov 2011 05:00 pm
Estoy justo verificando eso voy a dejar "prendido" server.php 1 hora y veremos elrendimiento y vigilare el task manager. y si, Inyaka tiene razon lo que he hecho es hacer recursiva la funcion , el nuevo socket queda a la escucha y solo la funcion se llama asi misma. Los mantendre al tanto de esto.

Por otro lado, Inyaka, no por ahora no deseo hacerlo funcionar con javascript, esta idea esmas para mantener dos servidores sincronizados, asi puedo hacer que lo que se vea y se cambie en el hosting que tiene el server.php se vea reflejado en el hosting con client.php. Para ojos de los que esten en frontEnd esta operacion es invisible. Esta idea la tome de imageshack api, para subir imagenes (a una cuenta especifica si lo deseabas) a modo de services, recibias los datos en XML de la imagen.

Hace años alguien hizo una clase para por medio de sockets enviar una imagen subida al servidor y desde ahi mandarla al imageshack api. Basicamente es como que crees estar subiendo una imagen a tu servidor, pero el almacenamiento es en el servidor de imageshack

Por Mr. X-ecutor

96 de clabLevel

1 tutorial

Genero:Masculino  

12/02/2007

firefox
Citar            
MensajeEscrito el 17 Nov 2011 07:01 pm
cuando se usen funciones recursivas, o procesos infinitos no te olvides del gran amigo sleep(),
o el favorito mio usleep(). los ciclos de reloj del procesador,hay que aprovecharlos mejor

Por tuadmin

Claber

598 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 17 Nov 2011 07:38 pm
Lo he tenido en funcionamiento casi 40 minutos y todo normal no ha presentado demoras en elrendimiento del equipo. Lo que si al apagar el apache se toma mas tiempo del normal. Pero para aseurarme de que no vaya a pasar nada le agregue una opcion para "apagar" el servidor. De paso lo volvi una clase estatica para evitar instancias:

server.php

Código PHP :

class SocketServer{
   private static $host;
    private static $port;
   private static $socket;
   public static $closed;
   public static $event;
   protected static $_instance;
    public function __construct($vhost='127.0.0.1',$vport=2356){
        if(!preg_match("/\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}/",$vhost)){
            trigger_error('Invalid IP address format.',E_USER_ERROR);
        }else{ echo $vhost; }
        if(!is_int($vport)||$vport<1||$vport>65535){
            trigger_error('Invalid TCP port number.',E_USER_ERROR);
        }
        self::$host=$vhost;
        self::$port=$vport;
        self::connect();
    }
   
   public static function getInstance() {
      if (!isset(self::$_instance)) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }
   
    public static function connect(){
        set_time_limit(0);
      self::$closed = false;
        // create low level socket
        if(!self::$socket=socket_create(AF_INET,SOCK_STREAM,0)){
            trigger_error('Error creating new socket.',E_USER_ERROR);
        }
        // bind socket to TCP port
        if(!socket_bind(self::$socket,self::$host,self::$port)){
            trigger_error('Error binding socket to TCP port.',E_USER_ERROR);
        }
        // begin listening connections
        if(!socket_listen(self::$socket)){
            trigger_error('Error listening socket connections.',E_USER_ERROR);
        }
        // create communication socket
        if(!$comSocket=socket_accept(self::$socket)){
            trigger_error('Error creating communication socket.',E_USER_ERROR);
        }
        // read socket input
        $socketInput=socket_read($comSocket,1024);
      if(!preg_match("/(.*)-closeAdmX$/", $socketInput)) { 
        // convert to uppercase socket input 
           $socketOutput=strtoupper(trim($socketInput));
        // write data back to socket server
           if(!socket_write($comSocket,$socketOutput,strlen($socketOutput))){
               trigger_error('Error writing socket output',E_USER_ERROR);
             }
      }else{
         self::$closed = true;
         $socketOutput=strtoupper(trim($socketInput))."<br>Closed the server by Admin (".self::$closed.")";
         if(!socket_write($comSocket,$socketOutput,strlen($socketOutput))){
               trigger_error('Error writing socket output',E_USER_ERROR);
             }
      }
        // close sockets
        socket_close($comSocket);
      self::$event = self::closeSocket();
    }
   private static function closeSocket() {
      socket_close(self::$socket);
      if (self::$closed == true) {
         $keep = false;
      }else{
         $keep = true;
      }
      return $keep;
   }
}

SocketServer::getInstance();
keepAlive();
function keepAlive() {
   if(SocketServer::$event == true) {
      SocketServer::connect();
      keepAlive();
   }else{
      return false;//else means the admin closed the service, bye bye socket ;)
   }
}


Aja, eso es muy cierto tuadmin, aunque no tengo idea de como usarlo en este caso ya que el proceso queda a la escucha, y no ejecuta otra linea hasta que suceda el evento del lado del socket cliente. Si aplicara una linea sleep de tantos segundos sucederia antes del listen o bien después de la llegada de la info del socket cliente.

Que recomendarías tu en este caso?

Por Mr. X-ecutor

96 de clabLevel

1 tutorial

Genero:Masculino  

12/02/2007

firefox
Citar            
MensajeEscrito el 17 Nov 2011 11:17 pm
pues en cada keepalive un ligero descanso

Código PHP :

function keepAlive() {
   if(SocketServer::$event == true) {
      SocketServer::connect();
      usleep(100);
      keepAlive();
   }else{
      return false;//else means the admin closed the service, bye bye socket ;)
   }
}

yo siempre uso sleep pero claro es por que yo trabajo en mi pc de 1 procesador pentium 4 , todos los trabajos lo hago pensando en computadoras de bajo rendimiento, cuando usaba mi servidor echo en puro php este presentaba el problema de que a ratos consumia el 80 o 90% en procesador, y la memoria dependiendo del php.ini en mi caso lo ponia a 128, la usaba a lleno, talvez el comportamiento es distinto en pcs con 4 nucleos.

Por tuadmin

Claber

598 de clabLevel



Genero:Masculino  

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.