3 years ago

Server sent events combined with XHR requests, help! :V


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.

    screenshot_2021-11-09_at_80043_pm.png
  • SO, I googled a bit, and found this: when I add the session_write_close(); line (in sse.php), the POSTs will get executed, but weirdly it doesn't affect the response by the sse.php

    screenshot_2021-11-09_at_80930_pm.png

    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 the sse.php code is clearly still running on the server!

    f5fe3dcb0cb264480fc635596c680f06.gif

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

Loading...

Next up

Flappy pizza delivery

It's Game Maker time, first time try

Maybe I'll share a functioning game after all these years? This one will be called Pizzalivery, I'll let you guess the silly game mechanics. I've created some cars in Asperite

Welcome to 'Mytherland' - a brand new interactive community website which will open very soon: https://myther.land

"Music Sounds Better with You" - Startdust

The Giga phat remix

They removed my verified badge

Also here's something silly, work-in-progress silly

Stole it from someone who stole it from someone

You may choose a letter, and I shall answer

(No you may not create 26 alt accounts to cover all letters of the alphabet lol)

Stickit' Truddy, web-project introduction

A website where you can Collect and Swap stickers with friends and fill up your collector's albums!

Join dev journey at gamejolt.com/c/stickit-kt5adm

#webdev #art