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;
                    }
                }
            }
        }
Esempio n. 2
0
        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;
                            }
                        }
                    }
                }
            }
        }