135 lines
4.0 KiB
PowerShell
135 lines
4.0 KiB
PowerShell
param(
|
|
[string]$BaseUrl = "http://localhost:8000",
|
|
[string]$Username,
|
|
[string]$Password,
|
|
[int]$ReadMessageCount = 5
|
|
)
|
|
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
if ([string]::IsNullOrWhiteSpace($Username) -or [string]::IsNullOrWhiteSpace($Password)) {
|
|
throw "Missing username/password. Pass -Username and -Password."
|
|
}
|
|
|
|
Add-Type -AssemblyName System.Net.Http
|
|
|
|
function Read-WebSocketMessage {
|
|
param(
|
|
[System.Net.WebSockets.ClientWebSocket]$Socket
|
|
)
|
|
|
|
$buffer = New-Object byte[] 8192
|
|
$segment = [System.ArraySegment[byte]]::new($buffer)
|
|
$builder = New-Object System.Text.StringBuilder
|
|
|
|
do {
|
|
$result = $Socket.ReceiveAsync($segment, [Threading.CancellationToken]::None).GetAwaiter().GetResult()
|
|
if ($result.MessageType -eq [System.Net.WebSockets.WebSocketMessageType]::Close) {
|
|
return $null
|
|
}
|
|
|
|
$builder.Append([System.Text.Encoding]::UTF8.GetString($buffer, 0, $result.Count)) | Out-Null
|
|
} while (-not $result.EndOfMessage)
|
|
|
|
return $builder.ToString()
|
|
}
|
|
|
|
$loginUri = "$BaseUrl/api/v1/auth/login"
|
|
$loginBody = "username=$([uri]::EscapeDataString($Username))&password=$([uri]::EscapeDataString($Password))"
|
|
|
|
Write-Host "Requesting access token from $loginUri ..."
|
|
$tokenResponse = Invoke-RestMethod `
|
|
-Method Post `
|
|
-Uri $loginUri `
|
|
-ContentType "application/x-www-form-urlencoded" `
|
|
-Body $loginBody
|
|
|
|
if (-not $tokenResponse.access_token) {
|
|
throw "Login succeeded but access_token missing."
|
|
}
|
|
|
|
$accessToken = [string]$tokenResponse.access_token
|
|
Write-Host "Token acquired. Expires in: $($tokenResponse.expires_in)"
|
|
|
|
$wsBase = $BaseUrl -replace "^http", "ws"
|
|
$wsUri = "$wsBase/ws?token=$accessToken"
|
|
|
|
$socket = [System.Net.WebSockets.ClientWebSocket]::new()
|
|
$socket.Options.KeepAliveInterval = [TimeSpan]::FromSeconds(20)
|
|
|
|
Write-Host "Connecting WebSocket: $wsUri"
|
|
$socket.ConnectAsync([Uri]$wsUri, [Threading.CancellationToken]::None).GetAwaiter().GetResult()
|
|
Write-Host "WebSocket connected."
|
|
|
|
try {
|
|
$initial = Read-WebSocketMessage -Socket $socket
|
|
if ($null -ne $initial) {
|
|
Write-Host ""
|
|
Write-Host "=== connection_established ==="
|
|
Write-Host $initial
|
|
}
|
|
|
|
$subscribeFrame = @{
|
|
type = "subscribe"
|
|
data = @{
|
|
channels = @("ue_scene")
|
|
}
|
|
} | ConvertTo-Json -Depth 8 -Compress
|
|
|
|
$subscribeBytes = [System.Text.Encoding]::UTF8.GetBytes($subscribeFrame)
|
|
$subscribeSegment = [System.ArraySegment[byte]]::new($subscribeBytes)
|
|
$socket.SendAsync(
|
|
$subscribeSegment,
|
|
[System.Net.WebSockets.WebSocketMessageType]::Text,
|
|
$true,
|
|
[Threading.CancellationToken]::None
|
|
).GetAwaiter().GetResult()
|
|
|
|
$subAck = Read-WebSocketMessage -Socket $socket
|
|
if ($null -ne $subAck) {
|
|
Write-Host ""
|
|
Write-Host "=== subscription_confirmed ==="
|
|
Write-Host $subAck
|
|
}
|
|
|
|
$syncFrame = @{
|
|
type = "sync_request"
|
|
data = @{
|
|
channel = "ue_scene"
|
|
reason = "initial_connect"
|
|
last_sequence = $null
|
|
}
|
|
} | ConvertTo-Json -Depth 8 -Compress
|
|
|
|
$syncBytes = [System.Text.Encoding]::UTF8.GetBytes($syncFrame)
|
|
$syncSegment = [System.ArraySegment[byte]]::new($syncBytes)
|
|
$socket.SendAsync(
|
|
$syncSegment,
|
|
[System.Net.WebSockets.WebSocketMessageType]::Text,
|
|
$true,
|
|
[Threading.CancellationToken]::None
|
|
).GetAwaiter().GetResult()
|
|
|
|
for ($i = 1; $i -le $ReadMessageCount; $i++) {
|
|
$message = Read-WebSocketMessage -Socket $socket
|
|
if ($null -eq $message) {
|
|
break
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "=== message $i ==="
|
|
Write-Host $message
|
|
}
|
|
}
|
|
finally {
|
|
if ($socket.State -eq [System.Net.WebSockets.WebSocketState]::Open) {
|
|
$socket.CloseAsync(
|
|
[System.Net.WebSockets.WebSocketCloseStatus]::NormalClosure,
|
|
"done",
|
|
[Threading.CancellationToken]::None
|
|
).GetAwaiter().GetResult()
|
|
}
|
|
$socket.Dispose()
|
|
}
|