1

I'm trying to create php stream application. The problem is that I can't allow two users to connect at the same time because, well they are paying for it so if they share stream it's useless.

So my solution was to add a row in my MySQL database where I would record if user is logged in with 1 and when user stops/cancels the stream record would be set back to 0. That's where the problem is I just can't detect when user aborted connection. I tried everything, I think: ignore_user_abort(true), while(!connection_aborted){readfile($stream)}...

I have multiple stream files but I'll put here the one that I think is the closest to solution. O and one more thing it worked for some time while I didn't use any kind of dynamic stream/username/password. So here goes the file:

<?php

require "../general/bootstrap.php"; // Include bootstrap
require "../general/error.php"; // Comertials when error

session_write_close();
ignore_user_abort(TRUE);
set_time_limit(0);

header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in history
header("Content-Transfer-Encoding: binary");
header("Cache-control: no-cache");
header('Pragma: no-cache');

if (count($items) != 3) {
    if (isset($items[1]) && !empty($items[1])) {
        $username = $items[1];
    } else {
        $username = null;
    }
    error("Missing one or more arguments(tv, username, password)!", $username);
}

$channel = (string) $items[0];
$username = (string) $items[1];
$password = (string) $items[2];

if (stream::channel_exists($channel)) {
    if (stream::channel_is_tv($channel)) {
        header('Content-Disposition: attachment; filename="stream.xspf"');
    } else {
        header('Content-Disposition: attachment; filename="stream.m3u"');
    }
} else {
    header('Content-Disposition: attachment; filename="stream.xspf"');
}

if (!stream::user_has_channel($username, $channel)) {
    error("User has requested channel '$channel' that it doesn't have!", $username);
}

if (!user::login($username, $password)) {
    error("Login failed! - probably because of trying to log in from 2 places at the same time or invalid username/password combination!", $username);
}

if (!isset($stream))
    $stream = stream::get_channel_stream($channel); // returns http://xxx.xxx.xxx.xxx/channel

function flush_buffers() {
    ob_end_flush();
    ob_flush();
    flush();
    //ob_start();
    fastcgi_finish_request();
}

// STREAM START
stream:
while(!connection_aborted() && user::is_enabled($username)) {
    readfile($stream);
    flush_buffers();
}
//STREAM END

sleep(10);

if(!connection_aborted()){
    goto stream;
}

user::logout($username);
exit();`

3 Answers3

2

If i understood it right this is what you neeed: http://php.net/manual/en/function.connection-aborted.php

  • 1
    Yea but if you saw I use that in the script posted up in my question I know everyone hates reading this long scripts but I use that! – user1606732 May 28 '13 at 10:28
0

One possible solution to this would be to execute the script as a thread and run it in the background with exec(), shell_exec or proc_open(). This way you can monitor the process and easily detect whether the script exited successfully or was aborted. I'd suggest using proc_open() as your easily able to open and monitor pipes.

Here are a few useful links dealing with proc_open()

http://php.net/manual/en/function.proc-open.php

http://www.molecularsciences.org/PHP/proc_open_tutorial_and_examples

http://phptutorial.info/?proc-open

Dan
  • 425
  • 2
  • 11
0

I meant to say, you should include those lines in the last if statement, using an else statement, so the user is logged out only when connection is aborted.

if(!connection_aborted())
   {
    goto stream;
   }
else
    user::logout($username);
    exit();`
   }

If you know the file size of the content you are streaming you can break the connection after the number of bytes have been transmited to the user.

likeitlikeit
  • 5,563
  • 5
  • 42
  • 56
Gimmy
  • 3,781
  • 2
  • 18
  • 27
  • Tnx, sorry but I didn't understand where should I put that it's on the end of the file! – user1606732 May 28 '13 at 10:36
  • I ment to say, you should include those lines in the last if statement, using an else statement, so the user is logout only when connection is aborted. – Gimmy May 28 '13 at 13:38
  • Ok but i don't usually do things like that because they are unnecessary. If user if still connected it'll go to stream back again which means that it can't possibly do anything else except download the stream. In the other hand if user is really disconnected then it'll logout and exit. Tnx anyways!! – user1606732 May 29 '13 at 14:54