1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
param ( [Parameter(Mandatory=$true)][string]$ServiceName, [Parameter(Mandatory=$true)][string]$IP = "192.168.0.5", [Parameter(Mandatory=$true)][string]$PortRange = "9999-9999" #[string]$password = $( Read-Host "Input password, please" ) ) #Make sure your port range is not large like 4000-7000 #[string]$ServiceName="MyServiceName" #[string]$IP = "192.168.0.5" #[string]$PortRange = "9999-9999" $session = New-Object Microsoft.PowerShell.Commands.WebRequestSession $Bytes = [System.Text.Encoding]::ASCII.GetBytes("USERNAME:PASSWORD") $Creds = [Convert]::ToBase64String($Bytes) $session.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36" try { $Response = Invoke-WebRequest -UseBasicParsing -Uri "http://192.168.0.1/setup.cgi?todo=nbtscan&next_file=FW_forward_service.htm" ` -WebSession $session ` -Headers @{ "Accept"="text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" "Accept-Encoding"="gzip, deflate" "Accept-Language"="en-US,en;q=0.9" "Authorization"="Basic $($Creds)" "Referer"="http://192.168.0.1/FW_forward.htm&todo=cfg_init" "Upgrade-Insecure-Requests"="1" } } catch { } $Response = Invoke-WebRequest -UseBasicParsing -Uri "http://192.168.0.1/setup.cgi?todo=nbtscan&next_file=FW_forward_service.htm" ` -WebSession $session ` -Headers @{ "Accept"="text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" "Accept-Encoding"="gzip, deflate" "Accept-Language"="en-US,en;q=0.9" "Authorization"="Basic $($Creds)" "Referer"="http://192.168.0.1/FW_forward.htm&todo=cfg_init" "Upgrade-Insecure-Requests"="1" } $URLID = $Response.Content | Select-String -Pattern "[0-9a-f]{16}" -AllMatches | % { $_.Matches.Value } #Request to add port $Body = "portname=$($ServiceName)&srvtype=BOTH&ex_port_range=$($PortRange)&same_range=use_same_port&in_port_range=$($PortRange)&server_ip1=192&server_ip2=168&server_ip3=0&server_ip4=$($IP.Split('.')[-1])&todo=pfw_add&h_pfw_name=$($ServiceName)&c4_pfw_ip=$($IP)&h_pfw_proto=0&h_pfw_ex_range=$($PortRange)&h_pfw_in_range=$($PortRange)&h_ruleSelect=0&ruleSelect=&edit=0&lanIP=192.168.0.1&h_srvtype=&c4_server_ip=&this_file=FW_forward_service.htm&next_file=FW_forward.htm&SID=" $URL = "http://192.168.0.1/setup.cgi?id=$($URLID)" $Response = Invoke-WebRequest -UseBasicParsing -Uri $URL ` -Method "POST" ` -WebSession $session ` -Headers @{ "Accept"="text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" "Accept-Encoding"="gzip, deflate" "Accept-Language"="en-US,en;q=0.9" "Authorization"="Basic $($Creds)" "Cache-Control"="max-age=0" "Origin"="http://192.168.0.1" "Referer"="http://192.168.0.1/setup.cgi?todo=nbtscan&next_file=FW_forward_service.htm" "Upgrade-Insecure-Requests"="1" } ` -ContentType "application/x-www-form-urlencoded" ` -Body $Body Start-Sleep -s 30 Write-Host "Removing" #Start to remove try { #Authenticate $Response = Invoke-WebRequest -UseBasicParsing -Uri "http://192.168.0.1/FW_forward.htm&todo=cfg_init" ` -WebSession $session ` -Headers @{ "Accept"="text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" "Accept-Encoding"="gzip, deflate" "Accept-Language"="en-US,en;q=0.9" "Authorization"="Basic $($Creds)" "Cache-Control"="max-age=0" "Referer"="http://192.168.0.1/adv_index.htm" "Upgrade-Insecure-Requests"="1" } } catch { } #Get Table Data $Response = Invoke-WebRequest -UseBasicParsing -Uri "http://192.168.0.1/FW_forward.htm&todo=cfg_init" ` -WebSession $session ` -Headers @{ "Accept"="text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" "Accept-Encoding"="gzip, deflate" "Accept-Language"="en-US,en;q=0.9" "Authorization"="Basic $($Creds)" "Referer"="http://192.168.0.1/adv_index.htm" "Upgrade-Insecure-Requests"="1" } $HTML = New-Object -Com "HTMLFile" [string]$htmlBody = $Response.Content $HTML.write([ref]$htmlBody) $HowManyRows = ($HTML.getElementById("PortForwarding").children[0].outerText.toString() | Measure-Object -Line).Lines - 1 write-host "Port forward Entries found: " $HowManyRows $FoundServiceID = 0 for ($i=1; $i -ile $HowManyRows; $i++) { #$HTML.getElementById("PortForwarding").children[0].children[$i].children[1].children[0].innerHTML() #$HTML.getElementById("PortForwarding").children[0].children[$i].children[2].children[0].innerHTML() #$HTML.getElementById("PortForwarding").children[0].children[$i].children[5].children[0].innerHTML() if ($HTML.getElementById("PortForwarding").children[0].children[$i].children[2].children[0].innerHTML() -eq $ServiceName) { $FoundServiceID = $i write-host "Found service at: " $i } } try { #Auth to remove $Response = Invoke-WebRequest -UseBasicParsing -Uri "http://192.168.0.1/setup.cgi?todo=nbtscan&next_file=FW_forward_service.htm" ` -WebSession $session ` -Headers @{ "Accept"="text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" "Accept-Encoding"="gzip, deflate" "Accept-Language"="en-US,en;q=0.9" "Authorization"="Basic $($Creds)" "Referer"="http://192.168.0.1/FW_forward.htm&todo=cfg_init" "Upgrade-Insecure-Requests"="1" } } catch { } #GetToken $URLID = $Response.Content | Select-String -Pattern "[0-9a-f]{16}" -AllMatches | % { $_.Matches.Value } $URL = "http://192.168.0.1/setup.cgi?id=$($URLID)" $DeleteBodyRequest = "serv_type=pf&svs_gm=FTP&SV_IP1=192&SV_IP2=168&SV_IP3=0&SV_IP4=&RouteSelect=$($FoundServiceID)&lanIP=192.168.0.1&h_pfw_name=&c4_pfw_ip=&h_pfw_proto=&h_pfw_ex_range=&h_pfw_in_range=&h_ruleSelect=$($FoundServiceID)&ruleSelect=$($FoundServiceID)&edit=&todo=delete&this_file=FW_forward.htm&next_file=FW_forward.htm&SID=" #Remove $Response = Invoke-WebRequest -UseBasicParsing -Uri $URL ` -Method "POST" ` -WebSession $session ` -Headers @{ "Accept"="text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" "Accept-Encoding"="gzip, deflate" "Accept-Language"="en-US,en;q=0.9" "Authorization"="Basic $($Creds)" "Cache-Control"="max-age=0" "Origin"="http://192.168.0.1" "Referer"="http://192.168.0.1/setup.cgi?id=$($URLID)" "Upgrade-Insecure-Requests"="1" } ` -ContentType "application/x-www-form-urlencoded" ` -Body $DeleteBodyRequest |
excluding folders for rapid republishing of a ASP.net project
Close your ASP project, open the .vbproj file with notepad and modify the following line (Target your Release build as that’s the one that gets published)
1 2 3 4 5 6 7 8 9 10 11 |
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> <DefineDebug>false</DefineDebug> <DefineTrace>true</DefineTrace> <Optimize>true</Optimize> <OutputPath>bin\</OutputPath> <DocumentationFile>MyProjectName.xml</DocumentationFile> <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022,42353,42354,42355</NoWarn> <Prefer32Bit>false</Prefer32Bit> <ExcludeFoldersFromDeployment>PDFS;Images;videos</ExcludeFoldersFromDeployment> </PropertyGroup> |
Handling WebSockets without SignalR in ASP.NET 4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<script lang="javascript"> var ConnectionString = "ws://" + location.host + "/Handler1.ashx"; //http://localhost:1981/Handler1.ashx console.log(ConnectionString); let socket = new WebSocket(ConnectionString); //, "protocolOne" socket.onopen = function(e) { document.body.innerHTML +=("[open] Connection established"); document.body.innerHTML +=("Sending to server"); socket.send("My name is John"); }; socket.onmessage = function(event) { document.body.innerHTML += (`[message] Data received from server: ${event.data}`); }; socket.onclose = function(event) { if (event.wasClean) { document.body.innerHTML += (`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`); } else { // e.g. server process killed or network down // event.code is usually 1006 in this case document.body.innerHTML += ('[close] Connection died'); } }; socket.onerror = function(error) { document.body.innerHTML += (`[error] ${error.message}`); }; </script> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
Imports System.Net.WebSockets Imports System.Threading Imports System.Threading.Tasks Imports System.Web Imports System.Web.Services Public Class Handler1 Implements System.Web.IHttpHandler Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest 'context.Response.ContentType = "text/plain" 'context.Response.Write("Hello World!") If (context.IsWebSocketRequest) Then context.AcceptWebSocketRequest(AddressOf HandleWebSocket) Else context.Response.StatusCode = 400 End If End Sub Private Async Function HandleWebSocket(ByVal wsContext As WebSocketContext) As Task Const maxMessageSize As Integer = 1024 Dim receiveBuffer As Byte() = New Byte(1023) {} Dim socket As WebSocket = wsContext.WebSocket Global_asax.WebSocketsConnected.Add(socket) While socket.State = WebSocketState.Open Dim receiveResult As WebSocketReceiveResult = Await socket.ReceiveAsync(New ArraySegment(Of Byte)(receiveBuffer), CancellationToken.None) If receiveResult.MessageType = WebSocketMessageType.Close Then Await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, CancellationToken.None) ElseIf receiveResult.MessageType = WebSocketMessageType.Binary Then Await socket.CloseAsync(WebSocketCloseStatus.InvalidMessageType, "Cannot accept binary frame", CancellationToken.None) Else Dim count As Integer = receiveResult.Count While receiveResult.EndOfMessage = False If count >= maxMessageSize Then Dim closeMessage As String = String.Format("Maximum message size: {0} bytes.", maxMessageSize) Await socket.CloseAsync(WebSocketCloseStatus.MessageTooBig, closeMessage, CancellationToken.None) Return End If receiveResult = Await socket.ReceiveAsync(New ArraySegment(Of Byte)(receiveBuffer, count, maxMessageSize - count), CancellationToken.None) count += receiveResult.Count End While Dim receivedString = Encoding.UTF8.GetString(receiveBuffer, 0, count) Dim echoString = "You said " & receivedString Dim outputBuffer As ArraySegment(Of Byte) = New ArraySegment(Of Byte)(Encoding.UTF8.GetBytes(echoString)) Await socket.SendAsync(outputBuffer, WebSocketMessageType.Text, True, CancellationToken.None) End If End While End Function ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable Get Return False End Get End Property End Class |
Add this line to allow current connections to be accessed.
1 2 3 4 5 6 7 8 9 10 11 12 |
Imports System.Net.WebSockets Imports System.Web.Optimization Public Class Global_asax Inherits HttpApplication Public Shared WebSocketsConnected As New List(Of WebSocket) '<--Add this Sub Application_Start(sender As Object, e As EventArgs) ' Fires when the application is started RouteConfig.RegisterRoutes(RouteTable.Routes) BundleConfig.RegisterBundles(BundleTable.Bundles) End Sub End Class |
Send data from another event to trigger to all connected websockets
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Public Class Contact Inherits Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load Dim Message As String = "Hello!!" Dim outputBuffer As ArraySegment(Of Byte) = New ArraySegment(Of Byte)(Encoding.UTF8.GetBytes(Message)) For Each MySocket As Net.WebSockets.WebSocket In Global_asax.WebSocketsConnected If MySocket.State = Net.WebSockets.WebSocketState.Open Then MySocket.SendAsync(outputBuffer, Net.WebSockets.WebSocketMessageType.Text, True, Threading.CancellationToken.None) End If Next End Sub End Class |
One last thing, you may also need to enable websockets if your on an older version of a project. Add or merge these params below into your system.web tag
1 |
<httpRuntime executionTimeout="300" targetFramework="4.7.2" /> |
And below is a sample of a test client form to use on Desktop machines to communicate with the server if needed, just update the URL to point to your source.
one thing to note, is when dealing with Websockets in this way you must avoid using .Wait on the main thread to prevent deadlocks. When the function itself is called it will halt on the first await command and never return. I think this is because the report data is being processed through the main message pump of the main thread and gets locked by using the wait() command. Its best to check the status in a loop with application.doevents and add a sleep if needed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
Imports System.Net Imports System.Net.WebSockets Imports System.Text Imports System.Threading Public Class Form1 Const maxMessageSize As Integer = 1024 Dim receiveBuffer As Byte() = New Byte(1023) {} Dim MySockets As New List(Of System.Net.WebSockets.ClientWebSocket) Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim socket As New System.Net.WebSockets.ClientWebSocket MySockets.Add(socket) Dim result As Task(Of Boolean) = myTask(socket) Exit Sub While result.Status <> TaskStatus.RanToCompletion Application.DoEvents() End While Debug.WriteLine(result.Status & " result: " & result.Result) ' "WaitingForActivation" Exit Sub ThisTest() Exit Sub End Sub Public Async Sub ThisTest() Dim ws = New System.Net.WebSockets.ClientWebSocket ' optional: ignore certificate errors Net.ServicePointManager.ServerCertificateValidationCallback = Function(s, c, h, d) True Try Await ws.ConnectAsync(New Uri("wss://demo.piesocket.com/v3/channel_1?api_key=oCdCMcMPQpbvNjUIzqtvF1d2X2okWpDQj4AwARJuAgtjhzKxVEjQU6IdCjwm¬ify_self"), Nothing) If (ws.State = WebSockets.WebSocketState.Open) Then Debug.Print("Opened.") Await ws.SendAsync(New ArraySegment(Of Byte)(System.Text.Encoding.UTF8.GetBytes("{ ""message"":""hello""}")), WebSockets.WebSocketMessageType.Text, True, Nothing) Dim bytes(4096) As Byte Dim answ = New ArraySegment(Of Byte)(bytes) Await ws.ReceiveAsync(answ, Nothing) Debug.Print("answer:" + System.Text.Encoding.UTF8.GetString(answ.Array)) Else Debug.Print("Not opened?!") End If Catch Debug.Print("Error.") End Try End Sub Private Async Function myTask(socket As System.Net.WebSockets.ClientWebSocket) As Task(Of Boolean) Dim myToken As New CancellationTokenSource(5000) Net.ServicePointManager.ServerCertificateValidationCallback = Function(s, c, h, d) True Await socket.ConnectAsync(New Uri("wss://demo.piesocket.com/v3/channel_1?api_key=oCdCMcMPQpbvNjUIzqtvF1d2X2okWpDQj4AwARJuAgtjhzKxVEjQU6IdCjwm¬ify_self"), myToken.Token) While Not socket.State = WebSocketState.Open Application.DoEvents() End While Dim count As Integer = 0 While socket.State = WebSocketState.Open Dim receiveResult As WebSocketReceiveResult = Await socket.ReceiveAsync(New ArraySegment(Of Byte)(receiveBuffer, 0, receiveBuffer.Length - 1), CancellationToken.None) Dim receivedString = Encoding.UTF8.GetString(receiveBuffer, 0, count) Dim echoString = "You said " & receivedString Dim outputBuffer As ArraySegment(Of Byte) = New ArraySegment(Of Byte)(Encoding.UTF8.GetBytes(echoString)) 'Await socket.SendAsync(outputBuffer, WebSocketMessageType.Text, True, CancellationToken.None) 'Debug.WriteLine("I Recv: " & System.Text.ASCIIEncoding.ASCII.GetString(receiveBuffer)) If receiveResult.MessageType = WebSocketMessageType.Close Then Await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, CancellationToken.None) ElseIf receiveResult.MessageType = WebSocketMessageType.Binary Then Await socket.CloseAsync(WebSocketCloseStatus.InvalidMessageType, "Cannot accept binary frame", CancellationToken.None) Else count = receiveResult.Count While receiveResult.EndOfMessage = False If count >= maxMessageSize Then Dim closeMessage As String = String.Format("Maximum message size: {0} bytes.", maxMessageSize) Await socket.CloseAsync(WebSocketCloseStatus.MessageTooBig, closeMessage, CancellationToken.None) Return False End If receiveResult = Await socket.ReceiveAsync(New ArraySegment(Of Byte)(receiveBuffer, count, maxMessageSize - count), CancellationToken.None) count += receiveResult.Count End While Debug.WriteLine("I Recv: " & System.Text.ASCIIEncoding.ASCII.GetString(receiveBuffer)) End If End While Return False End Function Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click For Each MySocket As ClientWebSocket In MySockets If MySocket.State = WebSocketState.Open Then Dim outputBuffer As ArraySegment(Of Byte) = New ArraySegment(Of Byte)(Encoding.UTF8.GetBytes("Got it!" & Now.TimeOfDay.ToString)) Debug.WriteLine("I Recv: " & System.Text.ASCIIEncoding.ASCII.GetString(receiveBuffer)) Await MySocket.SendAsync(outputBuffer, WebSocketMessageType.Text, True, CancellationToken.None) End If Next End Sub End Class |
Other useful links on this topic I found:
https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_server
https://www.esegece.com/websockets/main-components/net-components/net-websocket-client
https://mcguirev10.com/2019/08/17/how-to-close-websocket-correctly.html
Use this if you’d like to connect with powershell!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
Try{ Do{ $URL = 'ws://YourDOmain.com/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" [System.Text.Encoding]::utf8.GetString($Recv.array) } } Until ($WS.State -ne 'Open') }Finally{ If ($WS) { Write-Host "Closing websocket" $WS.Dispose() } } |
Read the Stockmarket with YahooFinanceAPI and VB.net
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
Imports YahooFinanceApi Imports System.Windows.Forms.DataVisualization.Charting 'https://github.com/lppkarl/YahooFinanceApi Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Refresh() Timer1.Interval = 15000 Timer1.Enabled = True End Sub Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Refresh() End Sub Private Async Sub Refresh() Dim QueryString As String = Nothing For Each MyItem In ComboBox1.Items QueryString &= MyItem & "," Next QueryString = QueryString.Remove(QueryString.Length - 1, 1) Debug.WriteLine(QueryString) Dim securities As IReadOnlyDictionary(Of String, Security) = Await Yahoo.Symbols(QueryString).Fields(Field.Symbol, Field.RegularMarketPrice, Field.RegularMarketTime, Field.Currency, Field.LongName).QueryAsync() Debug.WriteLine(securities) If lstResults.Items.Count > 0 Then lstResults.Items.Add(String.Empty) For Each objSecurity As Security In securities.Values Dim strCurrency As String Try 'for some reason, the currency is not always available! strCurrency = objSecurity.Currency Catch strCurrency = "(unknown)" End Try Dim strLongName As String Try strLongName = objSecurity.LongName Catch strLongName = "(unknown)" End Try Dim dtLatestPrice As DateTime = UnixTimeStampToDateTime(objSecurity.RegularMarketTime) lstResults.Items.Add($"{objSecurity.Symbol} @ {objSecurity.RegularMarketPrice} {strCurrency} - {dtLatestPrice} - {strLongName}") Next lstResults.SelectedIndex = lstResults.Items.Count - 1 End Sub Public Shared Function UnixTimeStampToDateTime(ByVal unixTimeStamp As Long) As DateTime Dim dtDateTime As DateTime = New DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc) dtDateTime = dtDateTime.AddSeconds(unixTimeStamp).ToLocalTime() Return dtDateTime End Function Private Sub ComboBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles ComboBox1.KeyDown If e.KeyData = Keys.Enter Then If Not ComboBox1.Items.Contains(ComboBox1.Text) Then ComboBox1.Items.Add(ComboBox1.Text) End If End If If e.KeyData = Keys.Delete Then ComboBox1.Items.RemoveAt(ComboBox1.SelectedIndex) End If End Sub Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged ShowHistory() End Sub Private Async Sub ShowHistory() Dim history = Await Yahoo.GetHistoricalAsync(ComboBox1.SelectedItem, DateTimePicker1.Value.ToShortDateString(), DateTimePicker2.Value.ToShortDateString(), Period.Daily) Dim s As Series Chart2.Series.Clear() If Not Chart1.Series.IsUniqueName(ComboBox1.SelectedItem) Then Chart1.Series.Item(ComboBox1.SelectedItem).Points.Clear() s = Chart1.Series.Item(ComboBox1.SelectedItem) Else s = New Series s.Name = ComboBox1.SelectedItem s.ChartType = SeriesChartType.Line End If For Each candle In history s.Points.AddXY(candle.DateTime.ToShortDateString, {candle.Close}) RichTextBox1.AppendText($"DateTime: {candle.DateTime}, Open: {candle.Open}, High: {candle.High}, Low: {candle.Low}, Close: {candle.Close}, Volume: {candle.Volume}, AdjustedClose: {candle.AdjustedClose}" & vbCrLf) Next If Chart1.Series.IsUniqueName(ComboBox1.SelectedItem) Then Chart1.Series.Add(s) End If Chart2.Series.Add(s) End Sub Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) End Sub Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick lstResults.Items.Clear() Refresh() End Sub End Class |
Using ASP.net without core to trigger Events on WebClient Javascript / RawSocket Client / and Server
With the following four blocks of code you can trigger events over an open connection through ASP.net (without core) to EventSource Javascript objects or .NET Think clients. Below is an example on how I tackled this issue.
This code is responsible for accepting connections both from HTTP, JS EventSource Listeners and .NET Think clients.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
Public Class JSEventHandler Inherits System.Web.UI.Page Public Shared CurrentConnections As New Dictionary(Of String, HttpResponse) Public Shared ConsoleConnections As New Dictionary(Of String, HttpResponse) Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim CurrentConnectionIndex As Integer = CurrentConnections.Count Debug.WriteLine(Request.QueryString("param")) If Request.UserAgent = "SomeValue" Or Request.QueryString("param") = "SomeValue" Then ConsoleConnections.Add(CurrentConnectionIndex, Response) Else If Request.QueryString("param") = "AnotherValue" Then CurrentConnections.Add(CurrentConnectionIndex, Response) End If If Request.QueryString("param") = "ThirdValue" Then CurrentConnections.Add(CurrentConnectionIndex, Response) End If End If Debug.WriteLine("Connection Added:" & CurrentConnectionIndex) Response.Clear() Dim FromNumber = Request.QueryString("FromNumber") Response.StatusCode = 200 Response.ContentType = "text/event-stream" Response.CacheControl = "no-cache" Response.Headers.Add("Access-Control-Allow-Origin", "*") Dim Tracker As Integer = 0 While Response.IsClientConnected Tracker += 1 System.Threading.Thread.Sleep(200) Response.Flush() 'If this is not used then the OpenMessage will not send If Tracker Mod 5 = 0 Then 'Debug.WriteLine("IsClientConnected: " & Response.IsClientConnected) End If End While If Request.UserAgent = "" Or Request.QueryString("param") = "SomeValue" Then CurrentConnections.Remove(CurrentConnectionIndex) Else If Request.QueryString("param") = "OtherValue" Then CurrentConnections.Remove(CurrentConnectionIndex) End If End If Debug.WriteLine("Connection Removed:" & CurrentConnectionIndex) Response.Close() End Sub End Class |
The code below is used to trigger from an external source to send data to both JS EventSource listeners and Raw .NET thickclients using .Net WebClient. Below is for Server -> to JS Event Source & .NETClient
This can be triggered from a web event or from a method call.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<WebMethod()> Public Function PushEventTest() As String Dim sentTo As String = "" For Each MyConnection In JSEventHandler.CurrentConnection Dim Response As HttpResponse = CType(MyConnection.Value, HttpResponse) Response.Write("id:eventidPushed" & vbLf) Response.Write("event:message" & vbLf) Response.Write("data: " & Newtonsoft.Json.JsonConvert.SerializeObject(Now) & vbLf) Response.Write(vbLf) Response.Flush() Response.Write("id: EOFEVENT" & vbLf & vbLf) Response.Flush() sentTo &= MyConnection.Key & ", " Next For Each MyConnection In JSEventHandler.ConsoleConnection Dim Response As HttpResponse = CType(MyConnection.Value, HttpResponse) Response.BinaryWrite({&HFF}) Response.BinaryWrite({&H1}) Response.BinaryWrite(BitConverter.GetBytes(Now.ToString.Length)) Response.Write(Now) Response.Flush() Next Return Now & " Send to Connection #: " & sentTo End Function Public Function PushJSEvent(ByVal ClientIDUserAgent As String, data As String) As String Dim sentTo As String = "" For Each MyConnection In JSEventHandler.CurrentConnections Dim myResponse As HttpResponse = CType(MyConnection.Value, HttpResponse) If True Then 'Debug.WriteLine(Request.UserAgent) End If myResponse.Write("id:eventidPushed" & vbLf) myResponse.Write("event:message" & vbLf) myResponse.Write("data: " & data.Replace(vbLf, "<br>") & vbLf) 'Newtonsoft.Json.JsonConvert.SerializeObject() myResponse.Write(vbLf) myResponse.Flush() myResponse.Write("id: EOFEVENT" & vbLf & vbLf) myResponse.Flush() sentTo &= MyConnection.Key & ", " Next Return Now & " Send to Conection #: " & sentTo End Function Private Function PushDCAClientStringData(ByVal ClientIDUserAgent As String, data As String) As Boolean For Each MyConnection In JSEventHandler.ConsoleConnections Dim Response As HttpResponse = CType(MyConnection.Value, HttpResponse) Response.BinaryWrite({&HFF}) Response.BinaryWrite({&H1}) Response.BinaryWrite(BitConverter.GetBytes(data.Length)) Response.Write(data) Response.Flush() Next Return True End Function |
The code below allows the server to handle incoming connections from a .NET Think Client sending POST EventTriggering Data
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Public Class JSStreamReader Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsNothing(Request.QueryString("SomeParam")) Or (Request.UserAgent = "SomeAgent") Then Debug.WriteLine(Request.QueryString("SomeParam") & " " & Request.UserAgent) Dim reader As New System.IO.StreamReader(HttpContext.Current.Request.InputStream) Dim requestFromPost As String = reader.ReadToEnd() Debug.WriteLine(requestFromPost) 'Take any action wanted based on what is sent End If End Sub End Class |
The code below allows the client to both send and receive event data from WebClient connections.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
Private Sub SendDataToServer() Try Dim myClient = New Net.WebClient() myClient.Headers.Add("User-Agent", "SomeAgentValue") Dim MyBytes() As Byte While True Dim Cmd As String = Console.ReadLine() MyBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(Cmd) myClient.UploadData("http://localhost:4858/JSStreamReader.aspx?SomeGetValue=SomeVarToActOn", "POST", MyBytes) End While Catch End Try End Sub Private Sub ReadDataFromServer() Try Dim myClient = New Net.WebClient() myClient.Headers.Add("User-Agent", "SomeAgentValue") Dim FullByteMessage() As Byte = {} Dim FullStringMessage As String = "" Dim MyBytes(0) As Byte Dim DataType(0) As Byte Dim MessageLength(3) As Byte Dim ResponseStrean As IO.Stream = myClient.OpenRead("http://localhost:4858/JSEventHandler.aspx?param=SomeParamValueToActOn") 'Use DCA for Raw Stream or you will get JSEventData While True ResponseStrean.Read(MyBytes, 0, MyBytes.Length) If MyBytes(0) = &HFF Then ResponseStrean.Read(DataType, 0, DataType.Length) ResponseStrean.Read(MessageLength, 0, MessageLength.Length) Dim MaxData As Integer = BitConverter.ToInt32(MessageLength) For i = 0 To MaxData - 1 ResponseStrean.Read(MyBytes, 0, MyBytes.Length) FullByteMessage = FullByteMessage.Concat(MyBytes).ToArray Next End If If DataType(0) = &H1 Then Dim Data As String = System.Text.ASCIIEncoding.ASCII.GetString(FullByteMessage) Debug.WriteLine(Data) Console.WriteLine(Data) End If FullByteMessage = {} End While ResponseStrean.Close() Catch ex As Exception Debug.WriteLine(ex.Message) End Try End Sub |