Skip to content

Commit 91dc286

Browse files
author
James Brundage
committed
feat: Get-WebSocket -Handshake ( Fixes #81 )
Also, improving internal docs
1 parent 4ef241e commit 91dc286

File tree

1 file changed

+54
-22
lines changed

1 file changed

+54
-22
lines changed

Commands/Get-WebSocket.ps1

Lines changed: 54 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ function Get-WebSocket {
262262
# If it is a ScriptBlock, it will be run with the output of the WebSocket passed as the first argument.
263263
# This will run after the socket is connected and the first message is received.
264264
[Parameter(ParameterSetName='WebSocketClient')]
265-
[Alias('Identify','Handshake')]
265+
[Alias('Identify')]
266266
[PSObject]
267267
$Handshake,
268268

@@ -380,78 +380,106 @@ function Get-WebSocket {
380380
$ExecutionContext.SessionState.PSVariable.Set($keyValue.Key, $keyValue.Value)
381381
}
382382

383+
# If we have no socket url,
383384
if ((-not $SocketUrl)) {
385+
# throw up an error.
384386
throw "No SocketUrl"
385387
}
386388

389+
# If the socket url does not have a scheme
387390
if (-not $SocketUrl.Scheme) {
391+
# assume `wss`
388392
$SocketUrl = [uri]"wss://$SocketUrl"
389-
} elseif ($SocketUrl.Scheme -match '^https?') {
393+
} elseif (
394+
# otherwise, if the scheme is http or https
395+
$SocketUrl.Scheme -match '^https?'
396+
) {
397+
# replace it with `ws` or `wss`
390398
$SocketUrl = $SocketUrl -replace '^http', 'ws'
391399
}
392400

401+
# If any query parameters were provided
393402
if ($QueryParameter) {
403+
# add them to the socket url
394404
$SocketUrl = [uri]"$($SocketUrl)$($SocketUrl.Query ? '&' : '?')$(@(
395-
foreach ($keyValuePair in $QueryParameter.GetEnumerator()) {
405+
foreach ($keyValuePair in $QueryParameter.GetEnumerator()) {
406+
# cannocially, each key value pair should be url encoded,
407+
# and multiple values should be passed multiple times.
396408
foreach ($value in $keyValuePair.Value) {
397-
$valueString = if ($value -is [bool] -or $value -is [switch]) {
398-
($value -as [bool] -as [string]).ToLower()
399-
} else {
400-
$value
401-
}
409+
$valueString =
410+
# If the value is a boolean or a switch,
411+
if ($value -is [bool] -or $value -is [switch]) {
412+
# convert it to a string and make it lowercase.
413+
($value -as [bool] -as [string]).ToLower()
414+
} else {
415+
# Otherwise, just stringify.
416+
"$value"
417+
}
402418
"$($keyValuePair.Key)=$([Web.HttpUtility]::UrlEncode($valueString).Replace('+', '%20'))"
403419
}
404420
}) -join '&')"
405421
}
406422

423+
# If we had not set a -BufferSize,
407424
if (-not $BufferSize) {
408-
$BufferSize = 64kb
425+
$BufferSize = 64kb # default to 64kb.
409426
}
410427

428+
# Create a cancellation token, as this will save syntax space
411429
$CT = [Threading.CancellationToken]::None
412430

431+
# If `$WebSocket `is not already a websocket
413432
if ($webSocket -isnot [Net.WebSockets.ClientWebSocket]) {
433+
# create a new socket
414434
$ws = [Net.WebSockets.ClientWebSocket]::new()
415435
if ($SubProtocol) {
436+
# and add the subprotocol
416437
$ws.Options.AddSubProtocol($SubProtocol)
417438
} else {
418439
$ws.Options.AddSubProtocol('json')
419440
}
441+
# If there are headers
420442
if ($Header) {
443+
# add them to the initial socket request.
421444
foreach ($headerKeyValue in $header.GetEnumerator()) {
422445
$ws.Options.SetRequestHeader($headerKeyValue.Key, $headerKeyValue.Value)
423446
}
424447
}
448+
# Now, let's try to connect to the WebSocket.
425449
$null = $ws.ConnectAsync($SocketUrl, $CT).Wait()
426450
} else {
427451
$ws = $WebSocket
428452
}
429453

454+
# Keep track of the time
430455
$webSocketStartTime = $Variable.WebSocketStartTime = [DateTime]::Now
456+
# and add the WebSocket to the variable dictionary, so we can access it later.
431457
$Variable.WebSocket = $ws
432458

433-
$MessageCount = [long]0
434-
$FilteredCount = [long]0
435-
$SkipCount = [long]0
459+
# Initialize some counters:
460+
$MessageCount = [long]0 # * The number of messages received
461+
$FilteredCount = [long]0 # * The number of messages filtered out
462+
$SkipCount = [long]0 # * The number of messages skipped
436463

437-
$saidHello = $null
438-
$shookHands = $null
439-
440-
:WebSocketMessageLoop while ($true) {
441-
if ($ws.State -ne 'Open') {
442-
if ($ws.CloseStatusDescription) {
443-
Write-Error $ws.CloseStatusDescription -TargetObject $ws
444-
}
445-
break
446-
}
464+
# Initialize variables related to handshaking
465+
$saidHello = $null # * Whether we have said hello
466+
$shookHands = $null # * Whether we have shaken hands
467+
468+
# This loop will run as long as the websocket is open.
469+
:WebSocketMessageLoop while ($ws.State -eq 'Open') {
470+
# If we've given a timeout for the websocket,
471+
# and the websocket has been open for longer than the timeout,
447472
if ($TimeOut -and ([DateTime]::Now - $webSocketStartTime) -gt $TimeOut) {
473+
# then it's closing time (you don't have to go home but you can't stay here).
448474
$ws.CloseAsync([Net.WebSockets.WebSocketCloseStatus]::NormalClosure, 'Timeout', $CT).Wait()
449475
break
450476
}
451477

478+
# If we've gotten the maximum number of messages,
452479
if ($Maximum -and (
453480
($MessageCount - $FilteredCount) -ge $Maximum
454481
)) {
482+
# then I can't even take any more responses.
455483
$ws.CloseAsync([Net.WebSockets.WebSocketCloseStatus]::NormalClosure, 'Maximum messages reached', $CT).Wait()
456484
break
457485
}
@@ -590,6 +618,10 @@ function Get-WebSocket {
590618
Write-Error $_
591619
}
592620
}
621+
622+
if ($ws.CloseStatusDescription) {
623+
Write-Error $ws.CloseStatusDescription -TargetObject $ws
624+
}
593625
}
594626
$SocketServerJob = {
595627
<#

0 commit comments

Comments
 (0)