I've discovered Sever Sent Events yesterday, I made a quick demo for myself, however I got stuck.
I don't exactly know if what I want to do is possible. I'd like to create a notification system, where you can interact with the server, send XHR/AJAX requests, but at the same time being able to poll the notifications from the server.
It doesn't work, I can't find much info on this combo
I've heard that SSE are only one way, you can't use the connection as a web-socket to communicate back and forth. Does the one way mean that I won't be able to execute any XHR commands in the meantime?
Here's my front-end code, pretty poopy code:
#html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Server Side Events Test</title>
</head>
<body>
<p>Start the connection</p>
<button id="btn_connect">Connect SSE</button>
<button id="btn_end">Close conn</button>
<h3>Notifications: <span id="notif_res">(disconnected)</span></h3>
<p>Notification actions</p>
<button id="btn_incr">Add notif</button>
<button id="btn_clear">Clear notifs</button>
<script>
let source = new EventSource("sse.php");
console.log(source.withCredentials);
console.log(source.readyState);
console.log(source.url);
source.onopen = function() {
console.log("Connection establshed");
}
source.onmessage = function(e) {
console.log("Recieved message:" + e.data);
// Change notif number
document.getElementById("notif_res").innerHTML = e.data;
}
source.onerror = function(e) {
console.log("Connection encountered an error", e);
}
document.getElementById("btn_end").addEventListener("click", function() {
console.log("Connection temrinated");
source.close();
});
// Increment notifications
document.getElementById("btn_incr").addEventListener("click", function(e){
let xhr = new XMLHttpRequest();
xhr.open("POST", "add_notification.php");
xhr.send();
});
// Delete all notifications
document.getElementById("btn_clear").addEventListener("click", function(e){
let xhr = new XMLHttpRequest();
xhr.open("POST", "clear_notification.php");
xhr.send();
});
</script>
</body>
</html>
Here's the sse.php code
#php
<?php
session_start();
header('Content-Type: text/event-stream');
// Setup
if (!isset($_SESSION['notif'])) {
$_SESSION['notif'] = 0;
}
while(1){
session_start();
echo "data: ".$_SESSION['notif']."\n\n";
// flush the output buffer and send echoed messages to the browser
while (ob_get_level() > 0) {
ob_end_flush();
}
flush();
// session_write_close();
if (Connection_aborted()) break;
sleep(1);
echo "data: HEYO\n\n";
while (ob_get_level() > 0) {
ob_end_flush();
}
flush();
sleep(1);
}
?>
The add an clear notifs just update the $_SESSION['notif']
variable. The response of sse.php is just a data oscillating between the number of notifications and the text "HEYO".
Two observations:
When I execute the code above, the
add_notification.php
POSTs will never get sent.SO, I googled a bit, and found this: when I add the
session_write_close();
line (insse.php
), the POSTs will get executed, but weirdly it doesn't affect the response by thesse.php
Here's a demo, the notifications count only changes when I reload the page, whereas the response of
add_notification.php
is clearly the incremented number of notifs, and at the same time thesse.php
code is clearly still running on the server!
Does the code I'm making make sense? Are you even able to combine these 2 tricks to create a subscription to a server for notifications, and at the same time being able to interact with the site's API through other xhr requests?
1 comment