Skip to content

PowerShell SSE Client

Akram El Assas edited this page Aug 24, 2026 · 1 revision

Prerequisites

  • Install PowerShell 5.0+ (pre-installed on modern Windows versions).
  • Open a PowerShell terminal or ISE session.

SSE Client Sample

Here is a sample PowerShell SSE client sse.ps1:

#Requires -Version 5.0

<#
.SYNOPSIS
    Wexflow Server-Sent Events (SSE) Client script for PowerShell 5.0.

.DESCRIPTION
    Authenticates with the Wexflow REST API, starts a specified workflow job,
    subscribes to the corresponding SSE endpoint, and streams status updates until completion.

.PARAMETER BaseUrl
    The base API endpoint URL for the Wexflow instance (default: "http://localhost:8000/api/v1").

.PARAMETER Username
    The Wexflow username for authentication (default: "admin").

.PARAMETER Password
    The Wexflow password for authentication.

.PARAMETER WorkflowId
    The integer ID of the workflow to execute and monitor (default: 41).

.EXAMPLE
    .\Invoke-WexflowSseClient.ps1 -Username "admin" -Password "wexflow2018" -WorkflowId 41
#>

[CmdletBinding()]
param(
    [string]$BaseUrl = "http://localhost:8000/api/v1",
    [string]$Username = "admin",
    [string]$Password = "wexflow2018",
    [int]$WorkflowId = 41
)

# Enforce TLS 1.2 for modern HTTP operations
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

# Assembly load for HttpClient
Add-Type -AssemblyName System.Net.Http

# Functions
function Get-WexflowToken {
    param(
        [string]$Url,
        [string]$User,
        [string]$Pass
    )
    
    $loginUrl = "$Url/login"
    $body = @{
        username      = $User
        password      = $Pass
        stayConnected = $false
    } | ConvertTo-Json

    # Perform REST Login
    $response = Invoke-RestMethod -Uri $loginUrl -Method Post -Body $body -ContentType "application/json"
    
    if (-not $response.access_token) {
        throw "Failed to acquire JWT access token from response."
    }
    
    return $response.access_token
}

function Start-WexflowJob {
    param(
        [string]$Url,
        [string]$Token,
        [int]$WfId
    )
    
    $startUrl = "$Url/start?w=$WfId"
    $headers = @{
        Authorization = "Bearer $Token"
    }

    # Start the workflow via POST request
    $jobId = Invoke-RestMethod -Uri $startUrl -Method Post -Headers $headers
    return $jobId
}

function Listen-WexflowSse {
    <#
    .SYNOPSIS
        Connects to the Server-Sent Events (SSE) endpoint and reads streamed lines.
    .DESCRIPTION
        Uses System.Net.Http.HttpClient to establish an HTTP GET request with 
        HttpCompletionOption.ResponseHeadersRead. This allows line-by-line streaming of
        data payload lines prefixed with 'data: '.
    #>
    param(
        [string]$Url,
        [string]$Token
    )

    $handler = New-Object System.Net.Http.HttpClientHandler
    $client = New-Object System.Net.Http.HttpClient($handler)
    
    # Configure required HTTP Headers for SSE stream listening
    $request = New-Object System.Net.Http.HttpRequestMessage([System.Net.Http.HttpMethod]::Get, $Url)
    $request.Headers.Accept.Add((New-Object System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/event-stream")))
    $request.Headers.Authorization = New-Object System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", $Token)

    Write-Host "[SSE] Connecting to SSE stream..." -ForegroundColor Cyan

    try {
        # ResponseHeadersRead is crucial: it prevents HttpClient from buffering the whole stream into memory
        $responseTask = $client.SendAsync($request, [System.Net.Http.HttpCompletionOption]::ResponseHeadersRead)
        $response = $responseTask.Result

        if (-not $response.IsSuccessStatusCode) {
            throw "SSE Request failed with HTTP Status: $($response.StatusCode) - $($response.ReasonPhrase)"
        }

        $streamTask = $response.Content.ReadAsStreamAsync()
        $stream = $streamTask.Result
        $reader = New-Object System.IO.StreamReader($stream)

        Write-Host "[SSE] Connection established. Listening for events..." -ForegroundColor Green

        # Loop through stream line-by-line as data events arrive
        while (-not $reader.EndOfStream) {
            $lineTask = $reader.ReadLineAsync()
            $line = $lineTask.Result

            if (-not [string]::IsNullOrWhiteSpace($line) -and $line.StartsWith("data: ")) {
                # Extract JSON payload after 'data: ' prefix
                $jsonString = $line.Substring("data: ".Length)
                
                Write-Host "`n[SSE Event Received]" -ForegroundColor Yellow
                
                try {
                    $eventData = $jsonString | ConvertFrom-Json
                    
                    # Display structured output properties
                    Write-Host "  Workflow ID  : $($eventData.workflowId)"
                    Write-Host "  Job ID       : $($eventData.jobId)"
                    Write-Host "  Name         : $($eventData.name)"
                    Write-Host "  Status       : $($eventData.status)" -ForegroundColor Magenta
                    Write-Host "  Description  : $($eventData.description)"

                    # Server closes stream once status is terminal (e.g., Done, Failed, Stopped)
                    # Break loop after reading first terminal status frame
                    break
                }
                catch {
                    Write-Warning "Failed to parse raw SSE JSON payload: $_"
                    Write-Host "Raw Payload: $jsonString"
                }
            }
        }
    }
    finally {
        # Cleanup HTTP connections
        if ($null -ne $reader) { $reader.Dispose() }
        if ($null -ne $stream) { $stream.Dispose() }
        if ($null -ne $client) { $client.Dispose() }
        Write-Host "`n[SSE] Connection closed." -ForegroundColor Cyan
    }
}

# Main Execution Script Logic
try {
    Write-Host "1. Logging into Wexflow ($BaseUrl)..." -ForegroundColor White
    $jwtToken = Get-WexflowToken -Url $BaseUrl -User $Username -Pass $Password
    Write-Host "   Token retrieved successfully." -ForegroundColor Green

    Write-Host "2. Starting Workflow ID: $WorkflowId..." -ForegroundColor White
    $jobId = Start-WexflowJob -Url $BaseUrl -Token $jwtToken -WfId $WorkflowId
    Write-Host "   Job started successfully. Job ID: $jobId" -ForegroundColor Green

    # Construct SSE URL endpoint: /api/v1/sse/{workflowId}/{jobId}
    $sseEndpoint = "$BaseUrl/sse/$WorkflowId/$jobId"

    Write-Host "3. Subscribing to Wexflow SSE Endpoint..." -ForegroundColor White
    Listen-WexflowSse -Url $sseEndpoint -Token $jwtToken
}
catch {
    Write-Error "Execution Failed: $_"
}

To run the client, execute the script in PowerShell:

.\sse.ps1
  1. Install Guide
  2. Migration Guide to v10.0
  3. HTTPS/SSL
  4. Screenshots
  5. Docker
  6. Configuration Guide
    1. Wexflow Server
    2. Wexflow.xml
    3. Admin Panel
    4. Authentication
  7. Persistence Providers
  8. Getting Started
  9. Android App
  10. Local Variables
  11. Global Variables
  12. REST Variables
  13. Functions
  14. Cron Scheduling
  15. Command Line Interface (CLI)
  16. REST API Reference
    1. Introduction
    2. JWT Authentication
    3. Sample Clients
      1. C# Client
      2. PowerShell Client
      3. JavaScript Client
      4. PHP Client
      5. Python Client
      6. Go Client
      7. Rust Client
      8. Ruby Client
      9. Java Client
      10. C++ Client
    4. Security Considerations
    5. Swagger
    6. Workflow Notifications via SSE
      1. C# SSE Client
      2. PowerShell SSE Client
      3. JavaScript SSE Client
      4. PHP SSE Client
      5. Python SSE Client
      6. Go SSE Client
      7. Rust SSE Client
      8. Ruby SSE Client
      9. Java SSE Client
      10. C++ SSE Client
    7. Endpoints
  17. Samples
    1. Sequential workflows
    2. Execution graph
    3. Flowchart workflows
      1. If
      2. While
      3. Switch
    4. Approval workflows
      1. Simple approval workflow
      2. OnRejected workflow event
      3. YouTube approval workflow
      4. Form submission approval workflow
    5. Workflow events
  18. Logging
  19. Custom Tasks
    1. Introduction
    2. General
      1. Creating a Custom Task
      2. Wexflow Task Class Example
      3. Task Status
      4. Settings
      5. Loading Files
      6. Loading Entities
      7. Need A Starting Point?
    3. Installing Your Custom Task in Wexflow
      1. .NET Framework 4.8 (Legacy Version)
      2. .NET 8.0+ (Stable Version)
      3. Referenced Assemblies
      4. Updating a Custom Task
      5. Using Your Custom Task
    4. Suspend/Resume
    5. Logging
    6. Files
    7. Entities
    8. Shared Memory
    9. Designer Integration
      1. Registering the Task
      2. Adding Settings
    10. How to Debug a Custom Task?
  20. Built-in Tasks
    1. File system tasks
    2. Encryption tasks
    3. Compression tasks
    4. Iso tasks
    5. Speech tasks
    6. Hashing tasks
    7. Process tasks
    8. Network tasks
    9. XML tasks
    10. SQL tasks
    11. WMI tasks
    12. Image tasks
    13. Audio and video tasks
    14. Email tasks
    15. Workflow tasks
    16. Social media tasks
    17. Waitable tasks
    18. Reporting tasks
    19. Web tasks
    20. Script tasks
    21. JSON and YAML tasks
    22. Entities tasks
    23. Flowchart tasks
    24. Approval tasks
    25. Notification tasks
    26. SMS tasks
  21. Run from Source
  22. Fork, Customize, and Sync

Clone this wiki locally