Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript, PHP - Using server-sent events with multiple, unique users?

I'm brand-new to SSE. There are plenty of simple/introductory texts on server sent events

  • Here
  • Here
  • Here

But none of them touch on using the same SSE file for multiple different users.

For example:

I have a site, where users log on. While logged on, they can view data that is unique and private to them. I'd like each user to have live updates while they are logged in, which may or may-not contain sensitive information. To do so I am implementing server-sent events:

JS (Straight out of one of the links)

var source;

if (!!window.EventSource) {
    source = new EventSource("sse.php");
} else {
    ...
}

source.addEventListener("message", function(e) {
    ... do stuff ...
}, false);

PHP

header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
header("Connection: keep-alive");

while (true) {
    $data = \\ query DB or any other source
    if ($data) {
        sendMessage($someID, $data);
    }
    sleep(2);
}

function sendMessage($id, $data) {
    echo "id: $id\n";
    echo "data: $data\n\n";
    ob_flush();
    flush();
}

But using it this way, am I only sending the data to the user who opened the sse.php source (i.e. each EventSource("sse.php") is a new, unique connection)? Or will everyone logged on, who has initialized the connection, receive the same data?

This SO answer touches on multiple users, by using unique events:

echo "event: ping\n";
$msg1="This is first user";
echo 'data: {"msg": "' . $msg1 . '"}';
echo "\n\n";

echo "event: notify\n";
$msg2="This is second user";
echo 'data: {"msg": "' . $msg2 . '"}';
echo "\n\n";

And then only listening for a certain event:

var evtSource = new EventSource("sender.php");
evtSource.addEventListener("ping", function(e) {
var obj = JSON.parse(e.data);
var r_msg = obj.msg;

But that hardly seems reasonable. If each user is supposed to be receiving their own private feed, then this method would require me to hard-code a unique event for each user. AND, as the original answer mentions, it does not prevent a slightly above-average user from intercepting and reading all the other messages too.

And, on top of it all, the sse.php file doesn't know which user it's gathering data for, so it would have to do all users, all the time.

How do I create one sse.php file, that can handle an unlimited number of unique users, and only send the data to the appropriate user? So:

  1. there must be a way to send some initialization data (i.e. unique user ID) to server-side file, and

  2. there must be a way for only that one particular user to receive the information gathered

like image 580
Birrel Avatar asked Oct 19 '22 08:10

Birrel


1 Answers

am I only sending the data to the user who opened the sse.php source

Yes.

Or will everyone logged on, who has initialized the connection, receive the same data?

No.

If each user is supposed to be receiving their own private feed, then this method would require me to hard-code a unique event for each user

Luckily no! The SSE "event" is for sending different types of events down a single connection to a single user. A use-case might be Facebook wanting to use one event for sending chat updates, another event for sending friend requests, another for sending ads to show, etc.

In my book (Data Push Apps with HTML5 SSE, http://shop.oreilly.com/product/0636920030928.do - apologies for the plug!) I argue that it is redundant, and better included as part of the json object you are pushing.

And, on top of it all, the sse.php file doesn't know which user ...

Cookies are sent. So the typical approach is to first login the user, create a cookie that authenticates them, then call the sse script. If using a server system with sessions support (e.g. PHP), then the cookies are an implementation detail.

POST data, and custom headers, cannot be sent. So if cookies are not an option you'd have to use GET to post some authentication id (but as you note, that is not the best type of security).

like image 181
Darren Cook Avatar answered Oct 29 '22 12:10

Darren Cook