How to use a Websocket client to open a long-lived connection to a URL, using PowerShell V2? How to use a Websocket client to open a long-lived connection to a URL, using PowerShell V2? powershell powershell

How to use a Websocket client to open a long-lived connection to a URL, using PowerShell V2?


It is possible to use .NET's System.Net.WebSockets.ClientWebSocket class to do this. You need to be running Windows 8 or Server 2012 or newer as your underlying OS to utilise this class, so therefore I think you'd have at least PowerShell v3 regardless (and as a result the ConvertFrom-Json cmdlet). You also need to make use of the System.ArraySegment .NET class.

I've created a simple framework that demonstrates how to use the various classes to interact with the Slack RTM API from a PowerShell script. You can find the project on GitHub here:https://github.com/markwragg/Powershell-SlackBot

I've also blogged about it in more detail here: http://wragg.io/powershell-slack-bot-using-the-real-time-messaging-api/


Oddly enough, I had this same need recently. Thanks to Mark Wragg, and his helpful link, here is a quick bit of code to get this going. You'll need at least Windows 8 and Server 2012 to make these things work.

Try{      Do{        $URL = 'ws://YOUR_URL_HERE/API/WebSocketHandler.ashx'        $WS = New-Object System.Net.WebSockets.ClientWebSocket                                                        $CT = New-Object System.Threading.CancellationToken        $WS.Options.UseDefaultCredentials = $true        #Get connected        $Conn = $WS.ConnectAsync($URL, $CT)        While (!$Conn.IsCompleted) {             Start-Sleep -Milliseconds 100         }        Write-Host "Connected to $($URL)"        $Size = 1024        $Array = [byte[]] @(,0) * $Size        #Send Starting Request        $Command = [System.Text.Encoding]::UTF8.GetBytes("ACTION=Command")        $Send = New-Object System.ArraySegment[byte] -ArgumentList @(,$Command)                    $Conn = $WS.SendAsync($Send, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, $CT)        While (!$Conn.IsCompleted) {             #Write-Host "Sleeping for 100 ms"            Start-Sleep -Milliseconds 100         }        Write-Host "Finished Sending Request"        #Start reading the received items        While ($WS.State -eq 'Open') {                                    $Recv = New-Object System.ArraySegment[byte] -ArgumentList @(,$Array)            $Conn = $WS.ReceiveAsync($Recv, $CT)            While (!$Conn.IsCompleted) {                     #Write-Host "Sleeping for 100 ms"                    Start-Sleep -Milliseconds 100             }            #Write-Host "Finished Receiving Request"            Write-Host [System.Text.Encoding]::utf8.GetString($Recv.array)        }       } Until ($WS.State -ne 'Open')}Finally{    If ($WS) {         Write-Host "Closing websocket"        $WS.Dispose()    }}