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

浪尽此生 提交于 2020-07-18 05:59:36

问题


I am trying to use PowerShell V2 (testing purposes) to initiate a real-time messaging (rtm) instance with Slack. But according to Slack's FAQ, to connect to their rtm API, I need to use the wss:// protocol via a Websocket client to stream events associated. I am also trying to make it an asynchronous connection (receiving as well as connecting).

This doesn't work :

$webSock = New-Object System.Net.WebSocket.ClientWebSocket
$client = New-Object System.Threading.CancellationToken

One other thing is that I need a function to convert from JSON in PowerShell V2.

I tried using this but it doesn't work too:

function ConvertFrom-Json20([object] $item){ 
    add-type -assembly system.web.extensions
    $ps_js=new-object system.web.script.serialization.javascriptSerializer

    #The comma operator is the array construction operator in PowerShell
    return ,$ps_js.DeserializeObject($item)
}

回答1:


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/




回答2:


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()
    }

}


来源:https://stackoverflow.com/questions/40257671/how-to-use-a-websocket-client-to-open-a-long-lived-connection-to-a-url-using-po

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!