@@ -262,7 +262,7 @@ function Get-WebSocket {
262
262
# If it is a ScriptBlock, it will be run with the output of the WebSocket passed as the first argument.
263
263
# This will run after the socket is connected and the first message is received.
264
264
[Parameter (ParameterSetName = ' WebSocketClient' )]
265
- [Alias (' Identify' , ' Handshake ' )]
265
+ [Alias (' Identify' )]
266
266
[PSObject ]
267
267
$Handshake ,
268
268
@@ -380,78 +380,106 @@ function Get-WebSocket {
380
380
$ExecutionContext.SessionState.PSVariable.Set ($keyValue.Key , $keyValue.Value )
381
381
}
382
382
383
+ # If we have no socket url,
383
384
if ((-not $SocketUrl )) {
385
+ # throw up an error.
384
386
throw " No SocketUrl"
385
387
}
386
388
389
+ # If the socket url does not have a scheme
387
390
if (-not $SocketUrl.Scheme ) {
391
+ # assume `wss`
388
392
$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`
390
398
$SocketUrl = $SocketUrl -replace ' ^http' , ' ws'
391
399
}
392
400
401
+ # If any query parameters were provided
393
402
if ($QueryParameter ) {
403
+ # add them to the socket url
394
404
$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.
396
408
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
+ }
402
418
" $ ( $keyValuePair.Key ) =$ ( [Web.HttpUtility ]::UrlEncode($valueString ).Replace(' +' , ' %20' )) "
403
419
}
404
420
}) -join ' &' ) "
405
421
}
406
422
423
+ # If we had not set a -BufferSize,
407
424
if (-not $BufferSize ) {
408
- $BufferSize = 64 kb
425
+ $BufferSize = 64 kb # default to 64kb.
409
426
}
410
427
428
+ # Create a cancellation token, as this will save syntax space
411
429
$CT = [Threading.CancellationToken ]::None
412
430
431
+ # If `$WebSocket `is not already a websocket
413
432
if ($webSocket -isnot [Net.WebSockets.ClientWebSocket ]) {
433
+ # create a new socket
414
434
$ws = [Net.WebSockets.ClientWebSocket ]::new()
415
435
if ($SubProtocol ) {
436
+ # and add the subprotocol
416
437
$ws.Options.AddSubProtocol ($SubProtocol )
417
438
} else {
418
439
$ws.Options.AddSubProtocol (' json' )
419
440
}
441
+ # If there are headers
420
442
if ($Header ) {
443
+ # add them to the initial socket request.
421
444
foreach ($headerKeyValue in $header.GetEnumerator ()) {
422
445
$ws.Options.SetRequestHeader ($headerKeyValue.Key , $headerKeyValue.Value )
423
446
}
424
447
}
448
+ # Now, let's try to connect to the WebSocket.
425
449
$null = $ws.ConnectAsync ($SocketUrl , $CT ).Wait()
426
450
} else {
427
451
$ws = $WebSocket
428
452
}
429
453
454
+ # Keep track of the time
430
455
$webSocketStartTime = $Variable.WebSocketStartTime = [DateTime ]::Now
456
+ # and add the WebSocket to the variable dictionary, so we can access it later.
431
457
$Variable.WebSocket = $ws
432
458
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
436
463
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,
447
472
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).
448
474
$ws.CloseAsync ([Net.WebSockets.WebSocketCloseStatus ]::NormalClosure, ' Timeout' , $CT ).Wait()
449
475
break
450
476
}
451
477
478
+ # If we've gotten the maximum number of messages,
452
479
if ($Maximum -and (
453
480
($MessageCount - $FilteredCount ) -ge $Maximum
454
481
)) {
482
+ # then I can't even take any more responses.
455
483
$ws.CloseAsync ([Net.WebSockets.WebSocketCloseStatus ]::NormalClosure, ' Maximum messages reached' , $CT ).Wait()
456
484
break
457
485
}
@@ -590,6 +618,10 @@ function Get-WebSocket {
590
618
Write-Error $_
591
619
}
592
620
}
621
+
622
+ if ($ws.CloseStatusDescription ) {
623
+ Write-Error $ws.CloseStatusDescription - TargetObject $ws
624
+ }
593
625
}
594
626
$SocketServerJob = {
595
627
<#
0 commit comments