bigskysoftware / htmx-extensions

159 stars 46 forks source link

SSE Closing Event Loop #4

Closed andrewkowalik closed 2 months ago

andrewkowalik commented 7 months ago

Not sure if there is a preferred way to raise questions/ideas here, apologies ahead of time.

I am wondering if there is a blessed way to close a SSE event loop. Thinking of a general case where you are checking on a job status and once complete, the server closing the connection. Closing the connection will just cause the client to restablish the request. When using HTMX one possible option is to do an hx-swap-oob to replace the element that create the SSE, cleanup fails here though and some exceptions are raised within HTMX on cleanup.

Happy to contribute but was unsure what the maintainers thought in this case.

GrimalDev commented 4 months ago

Hello, I have implemented the sse-close in my code from this new htmx extension implementation. I have been torturing myself with this for too long. I'm thinking that asking it here could give significant help to anyone with the same problem as me. I am trying to make my frontend receive 4 informations on the fly when my page loads. I have achieved something like this on my frontend code:

<script src="https://unpkg.com/htmx.org@2.0.0-beta1/dist/htmx.min.js"></script>
<script src="https://unpkg.com/htmx-ext-sse@2.0.0/sse.js"></script>
<div id="sse">
      <div hx-ext="sse" sse-connect="http://10.242.20.100:3030/tests?sse" sse-close="close" hx-swap="beforeend">
        <div class="htmx-indicator">Waiting for server...</div>
        <ul sse-swap="stats"></ul>
      </div>
    </div>

My backend is written in php and is very simple (for anyone curious, here it is)

header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Access-Control-Allow-Origin: http://127.0.0.1:8080');
header('Access-Control-Allow-Credentials: true');

for ($n = 0; $n < 5; $n++) {
        echo "event: stats\ndata: <li>Message $n</li>\n\n";
    ob_flush();
    flush();
    sleep(1);
    }
echo "event: close\n\n";

exit();

I base my frontend on the official updated documentation of the sse extension (the one update since a month ago). But after all that, I still get the error in my frontend console telling about an unexpected close from the backend (which is normal sice the backend php script just end)....

The Said "error": Event {isTrusted: true, type: 'error', target: EventSource, currentTarget: EventSource, eventPhase: 2, …}

Thank you for any help provided !

roharvey commented 4 months ago

@GrimalDev check the EventStream messages in Chrome's network tab for the SSE call. Two things: you probably need a tiny sleep after the close message to ensure it is actually delivered before the connection is closed; and you might need an empty data value along with the close event (I seem to recall this but I'm not really sure).

GrimalDev commented 4 months ago

@GrimalDev check the EventStream messages in Chrome's network tab for the SSE call. Two things: you probably need a tiny sleep after the close message to ensure it is actually delivered before the connection is closed; and you might need an empty data value along with the close event (I seem to recall this but I'm not really sure).

First, thank you for answering. I have linked you a screenshot of the networks tab in action, the sse request ends correctly from chromes point of view (I still added a little cooldown). If I open the sse endpoint in an empty tab for exemple, the request ends and never fires again. But as you can see on the screenshot, the the request is fired again from htmx's point of point. My theory is that the automatic backoff system sees an error and thinks the sse request hasn't been ended properly, thus provoking a new request.

image
roharvey commented 4 months ago

@GrimalDev I'm sorry, I should have looked a little closer at your import. The close function missed version 2.0.0, apparently. Try https://unpkg.com/htmx-ext-sse@2.1.0/sse.js

GrimalDev commented 4 months ago

@GrimalDev I'm sorry, I should have looked a little closer at your import. The close function missed version 2.0.0, apparently. Try https://unpkg.com/htmx-ext-sse@2.1.0/sse.js

WELL WELL, that is a nice point ! Thank you A LOT

Telroshan commented 2 months ago

Closing this now that you can indeed specify a sse-close attribute to define an event name that closes your SSE connection. Also note that PR #31 will add an event when a SSE connection is closed, with a param that will let you know why it was closed, allowing you to handle failures and normal closings differently if needed! (see #43 for that latter matter btw)