问题
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