private async Task SocketThreadAsync(HttpClient client, HttpContent httpContent, T eventArgs, string prioAndResourcePath) { using CancellationTokenSource cancelToken = new CancellationTokenSource(); //await Cs.SubscriptionService.SemaphoreSlim.WaitAsync(); HttpResponseMessage resp; Cs.SubscriptionService.SubscriptionSessions.TryGetValue(prioAndResourcePath, out var outSubscData); var uri = new Uri(string.Format(CultureInfo.InvariantCulture, Cs.TemplateUrl, Cs.Address.Full, "subscription")); resp = await client.PostAsync(uri, httpContent).ConfigureAwait(true); resp.EnsureSuccessStatusCode(); var header = resp.Headers.FirstOrDefault(p => p.Key == "Set-Cookie"); string abbCookie = header.Value.Last().Split('=')[1].Split(';')[0]; string sessionCookie = header.Value.First().Split(':')[0].Split('=')[1]; if (outSubscData.RequestQueue.Count == 1) { sessionCookie = outSubscData.Session; } using ClientWebSocket wSock = new ClientWebSocket(); wSock.Options.Credentials = new NetworkCredential(Cs.UAS.User, Cs.UAS.Password); wSock.Options.Proxy = null; CookieContainer cc = new CookieContainer(); cc.Add(new Uri($"https://{Cs.Address.Full}"), new Cookie("ABBCX", abbCookie, "/", Cs.Address.IP)); cc.Add(new Uri($"https://{Cs.Address.Full}"), new Cookie("-http-session-", sessionCookie, "/", Cs.Address.IP)); wSock.Options.Cookies = cc; #if NETCOREAPP3_1 wSock.Options.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { return(true); }; #endif wSock.Options.KeepAliveInterval = TimeSpan.FromMilliseconds(5000); wSock.Options.AddSubProtocol(Protocol); await wSock.ConnectAsync(new Uri(string.Format(CultureInfo.InvariantCulture, TemplateSocketUrl, Cs.Address.Full)), cancelToken.Token).ConfigureAwait(true); //If user tried to open more sockets while we were opening this one async, they will be combined in the last Task of the RequestQueue //and subscribed to in the same session as this one if (outSubscData.RequestQueue.Count > 1) { outSubscData.Session = sessionCookie; outSubscData.RequestQueue.Last().Start(); } outSubscData.RequestQueue.Clear(); var bArr = new byte[1024]; ArraySegment <byte> arr = new ArraySegment <byte>(bArr); SubscriptionSockets.Add(ValueChangedEventHandler, wSock); while (ValueChangedEventHandler != null) { try { var res = await wSock.ReceiveAsync(arr, cancelToken.Token).ConfigureAwait(true); if (ValueChangedEventHandler == null) { break; } var s = Encoding.ASCII.GetString(arr.Array); eventArgs.SetValueChanged(s); ValueChangedEventHandler(this, eventArgs); } catch (Exception ex) { if (ex is WebSocketException && wSock.State == WebSocketState.Aborted) { break; } } } }
private async Task SocketThreadAsync(HttpClient client, string ip, Dictionary <string, string> httpContent, UAS uas, CancellationToken cancelToken) { //post that you want to subscribe on values using (FormUrlEncodedContent fued = new FormUrlEncodedContent(httpContent)) { var resp = await client.PostAsync(new Uri($"http://{ip}/subscription"), fued).ConfigureAwait(true); resp.EnsureSuccessStatusCode(); //Get the ABB cookie, which will be used to connect to to the websocket var header = resp.Headers.FirstOrDefault(p => p.Key == "Set-Cookie"); var val = header.Value.Last(); string abbCookie = val.Split('=')[1].Split(';')[0]; //Setup the websocket connection using (ClientWebSocket wSock = new ClientWebSocket()) { wSock.Options.Credentials = new NetworkCredential(uas.User, uas.Password); wSock.Options.Proxy = null; CookieContainer cc = new CookieContainer(); cc.Add(new Uri($"http://{ip}"), new Cookie("ABBCX", abbCookie, "/", ip)); wSock.Options.Cookies = cc; wSock.Options.KeepAliveInterval = TimeSpan.FromMilliseconds(5000); wSock.Options.AddSubProtocol("robapi2_subscription"); //Connect await wSock.ConnectAsync(new Uri($"ws://{ip}/poll"), cancelToken).ConfigureAwait(true); var bArr = new byte[1024]; ArraySegment <byte> arr = new ArraySegment <byte>(bArr); SubscriptionSockets.Add(ValueChangedEventHandler, wSock); while (ValueChangedEventHandler != null) { try { var res = await wSock.ReceiveAsync(arr, cancelToken).ConfigureAwait(true); if (ValueChangedEventHandler == null) { break; } //parse message var s = Encoding.ASCII.GetString(arr.Array); s = s.Split(new string[] { "lvalue\">" }, StringSplitOptions.None)[1].Split('<')[0].Trim(); ValueChangedEventHandler(this, new IOEventArgs() { LValue = int.Parse(s, CultureInfo.InvariantCulture) }); } catch (Exception ex) { if (ex is WebSocketException && wSock.State == WebSocketState.Aborted) { break; } } } } } }