SSE Broadcast
Keep an SSE connection open and broadcast events to all connected clients.
Full source
File: pwsh/tutorial/examples/15.10-SseBroadcast.ps1
<#
Create a broadcast SSE demo server with Kestrun in PowerShell.
FileName: 15.10-SseBroadcast.ps1
This demo shows server-side broadcasting to all connected SSE clients.
Broadcast SSE pieces:
- Add-KrSseBroadcastMiddleware (registers broadcaster + maps /sse/broadcast)
- Send-KrSseBroadcastEvent (broadcasts to all connected clients)
Per-request SSE helpers (still available):
- Start-KrSseResponse
- Write-KrSseEvent
#>
param(
[int]$Port = 5000,
[IPAddress]$IPAddress = [IPAddress]::Loopback
)
if (-not (Get-Module Kestrun)) { Import-Module Kestrun }
Initialize-KrRoot -Path $PSScriptRoot
New-KrLogger |
Set-KrLoggerLevel -Value Debug |
Add-KrSinkConsole | Register-KrLogger -Name 'SseBroadcastDemo' -SetAsDefault
New-KrServer -Name 'Kestrun SSE Broadcast Demo'
Add-KrEndpoint -Port $Port -IPAddress $IPAddress
# Add the broadcast SSE endpoints (implemented in C#; keeps connections open)
# 1) Default broadcast SSE stream (schema defaults to string in OpenAPI)
Add-KrSseBroadcastMiddleware -Path '/sse/broadcast' -KeepAliveSeconds 15
# 2) Progress broadcast SSE stream (OpenAPI payload schema: OperationProgressEvent)
Add-KrSseBroadcastMiddleware -Path '/sse/broadcast/progress' -KeepAliveSeconds 15
Enable-KrConfiguration
# Home page
Add-KrHtmlTemplateRoute -Pattern '/' -HtmlTemplatePath 'Assets/wwwroot/sseBroadcast.html'
# Broadcast API
Add-KrMapRoute -Verbs Post -Pattern '/api/broadcast' {
try {
$body = Get-KrRequestBody
$eventName = [string]($body.event ?? 'message')
$dataObj = $body.data
if ($null -eq $dataObj) { $dataObj = @{ text = 'empty' } }
$dataJson = $dataObj | ConvertTo-Json -Compress
Send-KrSseBroadcastEvent -Event $eventName -Data $dataJson
$count = Get-KrSseConnectedClientCount
Write-KrJsonResponse -InputObject @{ ok = $true; event = $eventName; connected = $count } -StatusCode 200
} catch {
Write-KrLog -Level Error -Exception $_.Exception -Message 'Send-KrSseBroadcastEvent failed: {error}' -Values $_.ToString()
# Generate error response
$err = [SseBroadcastErrorResponse]::new()
$err.ok = $false
$err.error = 'Sse Broadcast failed. See server logs for details.'
Write-KrJsonResponse -InputObject $err -StatusCode 500
}
}
# Progress Broadcast API
Add-KrMapRoute -Verbs Post -Pattern '/api/broadcast/progress' {
try {
$body = Get-KrRequestBody
$payload = @{
taskId = [string]($body.taskId ?? 'task-1')
progress = [double]($body.progress ?? 0)
status = [string]($body.status ?? 'Working...')
state = [string]($body.state ?? 'running')
ts = (Get-Date).ToUniversalTime()
}
$dataJson = $payload | ConvertTo-Json -Compress
Send-KrSseBroadcastEvent -Event 'progress' -Data $dataJson
$count = Get-KrSseConnectedClientCount
Write-KrJsonResponse -InputObject @{ ok = $true; event = 'progress'; connected = $count } -StatusCode 200
} catch {
Write-KrLog -Level Error -Exception $_.Exception -Message 'Send-KrSseBroadcastEvent failed: {error}' -Values $_.ToString()
# Generate error response
$err = [SseBroadcastErrorResponse]::new()
$err.ok = $false
$err.error = 'Sse Broadcast failed. See server logs for details.'
Write-KrJsonResponse -InputObject $err -StatusCode 500
}
}
Write-Host '๐ข Kestrun SSE Broadcast Demo Server Started' -ForegroundColor Green
Write-Host "๐ Navigate to http://localhost:$Port" -ForegroundColor Cyan
Write-Host "๐ก Broadcast SSE endpoint: http://localhost:$Port/sse/broadcast" -ForegroundColor Cyan
Write-Host "๐ Progress SSE endpoint: http://localhost:$Port/sse/broadcast/progress" -ForegroundColor Cyan
Start-KrServer -CloseLogsOnExit
Step-by-step
- Logging: Register a console logger as default.
- Server: Create a server and listener (IP + port).
- Broadcast SSE: Add
Add-KrSseBroadcastMiddlewareto expose/sse/broadcast. - Configuration: Enable configuration so middleware and routes are active.
- Home page: Serve an HTML demo with an
EventSource('/sse/broadcast')client. - Broadcast API: Implement
POST /api/broadcastto accept{ event, data }JSON. - Broadcast: Send events to all clients using
Send-KrSseBroadcastEvent. - Run: Start the server, connect clients, then broadcast messages.
Try it
Start the server:
pwsh .\docs\_includes\examples\pwsh\15.10-SseBroadcast.ps1
Open the demo UI and connect:
Start-Process http://127.0.0.1:5000/
Broadcast a message via the API:
curl -i -X POST http://127.0.0.1:5000/api/broadcast \
-H "Content-Type: application/json" \
-d "{\"event\":\"message\",\"data\":{\"text\":\"hello\"}}"
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| SSE stream never shows events | No clients connected | Connect a client to /sse/broadcast before broadcasting. |
| Broadcast API returns 500 | Bad JSON body | Ensure Content-Type: application/json and send { event, data }. |
| Browser reconnect loop | Connection interrupted | Check proxies/load balancers; increase -KeepAliveSeconds to keep intermediaries from timing out. |
References
- Add-KrSseBroadcastMiddleware
- Send-KrSseBroadcastEvent
- Get-KrSseConnectedClientCount
- Get-KrRequestBody
- Write-KrJsonResponse
- Write-KrHtmlResponse
- Enable-KrConfiguration
- Start-KrServer