1

I'm trying to implement simple application using PHP (unfortunately it must be in PHP) with sockets. I have one page - let's say multi.php and many instances of page client.php I wan't to send some data to all instances of client.php from one instance of multi.php without files or databases.

I tried to do it using multicast (send some data from multi.php using multicast address) but it doesn't work. I can't communicate with any instance of client.php

Thank you in advance

Lukasz Spas
  • 595
  • 2
  • 9
  • 23
  • What do you call an instance of `client.php` ? a script is instantiated once for each HTTP request and destroyed right when the HTTP response is send. PHP has no active code running in apache that survives between HTTP requests. – Frederic Bazin Jun 09 '11 at 19:42
  • Thats not totally correct. If PHP is running in Apache or other Httpds you can set `max_execution_time` to 0 and set `inore_user_abbort(true)`. In that case a php script would even run in a webserver until it finishes or the webseerver is shutdown, and in that case it has no effect if the HTTP request ist finished or not. And if you are running php scripts on commandline, the won`t have a limit for runtime by default. – Radon8472 Oct 28 '13 at 06:40

2 Answers2

4

I am currently building a class in PHP, for private use. With the class I am will control MediaRender devices. In the mSearch method you can see an example on how to achieve a multicast effect in PHP.

    // BUILD MESSAGE
    $msg  = 'M-SEARCH * HTTP/1.1' . "\r\n";
    $msg .= 'HOST: 239.255.255.250:1900' ."\r\n";
    $msg .= 'MAN: "'. $man .'"' . "\r\n";
    $msg .= 'MX: '. $mx ."\r\n";
    $msg .= 'ST:' . $st ."\r\n";
    $msg .= 'USER-AGENT: '. static::USER_AGENT ."\r\n";
    $msg .= '' ."\r\n";

    // MULTICAST MESSAGE
    $sock = socket_create( AF_INET, SOCK_DGRAM, 0 );
    $opt_ret = socket_set_option( $sock, 1, 6, TRUE );
    $send_ret = socket_sendto( $sock, $msg, strlen( $msg ), 0, '239.255.255.250', 1900);

    // SET TIMEOUT FOR RECIEVE
    socket_set_option( $sock, SOL_SOCKET, SO_RCVTIMEO, array( 'sec'=>$sockTimout, 'usec'=>'0' ) );

    // RECIEVE RESPONSE
    $response = array();
    do {
        $buf = null;
        @socket_recvfrom( $sock, $buf, 1024, MSG_WAITALL, $from, $port );
        if( !is_null($buf) )$response[] = $this->parseMSearchResponse( $buf );
    } while( !is_null($buf) );

    // CLOSE SOCKET
    socket_close( $sock );

https://github.com/artheus/PHP-UPnP/blob/development/phpupnp.class.php

Morten Hekkvang
  • 356
  • 2
  • 7
  • I call it a "multicast effect" as I am not sure about if this is actually following the technical term of "multicasting" fully as a standard. Would be nice to know if it is though. – Morten Hekkvang Nov 05 '12 at 09:10
  • What does `socket_set_option( $sock, 1, 6, TRUE )` mean? What is `1` and `6`? I got this warning when I use this code: `PHP Warning: socket_set_option(): unable to set socket option [22]: Invalid argument` – TheFox Apr 20 '14 at 14:27
0

You cannot do multicast with PHP for now. See http://bugs.php.net/bug.php?id=40510

What you CAN do is simply send the same data to all sockets. You have one server process (multi.php) accepting connections. This process simply sends the same data to all open connections. Is this what you try to achieve?

ckruse
  • 9,642
  • 1
  • 25
  • 25
  • more or less... in yours solution I need to connect from client.php to multi.php and retrieve data. multi.php needs to work in background. But in my problem multi.php starts to put some data and it quit... all instances of client.php need to work in background and listen for data. – Lukasz Spas Jun 09 '11 at 19:59
  • So what you really try to do is send a broadcast to all client.php processes? This is not easy. You are very limited in your prerequisites. I think you have to register all started client.php processes somewhere where the multi.php could request a list of all valid client.php processes. Are your processes on the same physical machine? Then you could use some IPC methods, e.g. a semaphore or a shared memory segment. – ckruse Jun 09 '11 at 20:08
  • Yes, all processes are on the same physical machine. shared memory might be a good solution. I have one more idea but I can't find how to implement it - is there any possibility to notify all instances of client.php that somewhere is some new data (for example in some file or database)? just only notification.. – Lukasz Spas Jun 09 '11 at 21:21
  • Yes, you can. Either by using a semaphore (you can wait on semaphores) or by getting a list of all processes (the easiest way would be `ps ax`) and send a signal (e.g. SIGUSR1). The client.php processes would set up a signal handler on this specific signal. – ckruse Jun 09 '11 at 21:27