Pode icon indicating copy to clipboard operation
Pode copied to clipboard

Improved SSE/WebSocket connection handling, additional events for SSE/WebSockets/Auth, manual upgrade control for WebSockets

Open Badgerati opened this issue 3 weeks ago • 2 comments

Description

This is a hefty PR that covers various improvements and fixes, but also new features, for #1547 and #1548 - but primarily for Pode.Web to resolve stability and clean-up issues with SSE and WebSocket (Signal) connections (for example: https://github.com/Badgerati/Pode.Web/issues/660)

The Great Refactor

Ultimately a lot of the underlying logic for SSE/WebSockets has been refactored, to far better handle when clients disconnect and to enable Pode to be aware of this fact.

For WebSockets, fortunately, a lot of this is handled for us by inbuilt JS WebSocket libraries - if the client disconnects it will inform the server via a close event. This said however, Pode now has a Timer which will periodically call connected clients with a ping event - same as how the clients "ping" the server - in case that close event is never called. If the ping event to the client fails, the client has disconnected.

For SSE we have to rely on a Timer, this timer will also periodically send a pode.ping event to connected clients - similar to the existing pode.open and pode.close events. If the pode.ping event to the client fails, the client has disconnected.

Knowing these disconnected clients, Pode can now clean-up the resources. These events are configured to occur roughly every 60 seconds.

Manual WebSocket Control

Unlike SSE where you have full control over when the HTTP request is upgraded via ConvertTo-PodeSseConnection, WebSockets (Signals) have always been "auto-upgraded". This meant you had zero control over the ClientId sent back, no control over when the upgrade actually occurred, but more importantly zero HTTP authentication support on that upgrade.

Well, there's now a ConvertTo-PodeSignalConnection which works in the same manner as the SSE counterpart. The auto-upgrading is still the default functionality for backwards compatibility, but you can disable this by supplying -NoAutoUpgradeWebSockets to the relevant HTTP/WS Add-PodeEndpoint. To upgrade the HTTP request to a Signal connection simply invoke ConvertTo-PodeSignalConnection from an Add-PodeRoute.

More Events

Now that we can track client connections and disconnections, there are some new Events (Connected/Disconnected) and Functions for SSE and Signals:

  • Register-PodeSseEvent
  • Unregister-PodeSseEvent
  • Test-PodeSseEvent
  • Get-PodeSseEvent
  • Register-PodeSignalEvent
  • Unregister-PodeSignalEvent
  • Test-PodeSignalEvent
  • Get-PodeSignalEvent

Whenever an event is triggered, the event's scriptblock will be triggered and details about the client connection will be supplied - such as ClientId, Group, Type, etc. as a $TriggeredEvent.Connection.[...]

Furthermore, there are now also new Events (Login/Logout) and Functions for end-user authentication (eg, Add-PodeAuth):

  • Register-PodeAuthEvent
  • Unregister-PodeAuthEvent
  • Test-PodeAuthEvent
  • Get-PodeAuthEvent

Whenever an end-user logs in successfully, or logouts, these events will be triggered and supplied the User object as $TriggeredEvent.User, and the Name of the Authentication method which triggered the login/logout - in the case of merged authentication strategies the event will be triggered for the valid authentication plus the chain of parent authentication methods.

Added / Fixes

  • Improved connection clean-up for disconnected SSE/WebSocket clients
  • Support for manual WebSocket connection upgrading
  • Support for custom WebSocket Client IDs
  • Support for HTTP Authentication on clients connecting to WebSocket Endpoints
  • Added Events for SSE/WebSocket client connect and disconnects
  • Added Events for Authentication logins and logouts

Badgerati avatar Dec 01 '25 23:12 Badgerati

Bit more testing to do on the Pode.Web side, otherwise it's mostly just updating the docs that's left to do.

Badgerati avatar Dec 02 '25 22:12 Badgerati

Just wanted to say a quick thank you for investigating the sockets issue, we would love to upgrade to 1.0.0 but that issue and a few others held us back. We concluded at the time mostly from lack of understanding of that issue that it was best to stay on 0.8.3. It's worked well for us, but we would love to move to 1.0.0 once it's ready!!

Really glad to see activity here :). You have a terrific project.

thoffmannaspenware avatar Dec 09 '25 02:12 thoffmannaspenware