17 Replies Latest reply: Sep 8, 2017 6:20 AM by Øystein Kolsrud RSS

    .NetSdk - Connection failed after 4 attempts

    René Engler

      Hi Guys,

       

      we use .NetSDK to integrate QlikSense in an ERP - system. Now we are faced with following problem:

           We are not able to cache the Location or the Connection, so we have to connect us with the QlikSense Server several times. But      after these attempts an error occurs:

      Exception NAVdiscovery.png

      It also affects the hub. The user has no access.

      2015-09-22 10_09_53-Qlik Sense.png

      Do you have a solution for this issue?

      (I reconstructed this with the engine API, but there is a similar problem. After several method calls I receive an errormessage, which includes the information, that the server has canceled the connection)

       

      Thank you

      René

        • Re: .NetSdk - Connection failed after 4 attempts
          Randy Holder

          I too have run into this issue. Everything was working fine until upgrading to Qlik Sense 2.1.1

          • Re: .NetSdk - Connection failed after 4 attempts
            Alexander Karlsson

            Hey,

             

            Are you opening additional apps?
            Each license is limited to 5 concurrent sessions so make sure you tidy up and close your sessions as you switch between apps.

            • Re: .NetSdk - Connection failed after 4 attempts
              Lars-Goran Book

              Hi,
              Lots of questions and confusions here, I will try sort this out.
              There are three types of sessions :
              Engine Session
              Proxy Session
              QlikConnection Session (.Net SDK)

              The engine session is built up of user id and session id, you can use the .Net SDKs Session.WithApp(IAppIdentifier appIdentifier,

              SessionType sessionType) to control the connect to the engine session. SessionType.Default is the same session as the clients session.
              You can also create you own session ids or use the SessionType.Random.

              The proxy session which is the connection to Qlik Sense instance (and affects the license user/token) and corresponds to a .Net SDK

              Location. Your Location will tipically be created with "Location.FromUri". The location can be reused for many apps.
              When the Location goes out of scope it will be disposed within the SDK but the liceense token will stil remain active for 30 minutes (this can be modified in the qmc).
              If you wish to drop he license before 30 minutes you must do a Logout (REST call) to the proxy to drop that license token, more information

              can be found in the Qlik Sense Proxy Service API under the help pages.

               

              Best practice is to create one Qlik.Engine.Location and reuse this between different Qlik Sense applications. If you need more than one create as many as you need, but be aware of licenses.

              Example:
              try
              {
                using (ILocation local = Qlik.Engine.Location.FromUri(new Uri("https://myserver.domain.com")))
                {
                  local.AsNtlmUserViaProxy();

                  foreach (var entry in local.GetAppIdentifiers())
                  {
                    try
                    {
                      using (var app = local.App(entry))
                      {
                        var reloadSucceded = app.DoReload();
                 // do other work
                      } // the engine session and .Net SDKs Session are disposed.
                    }
                    catch (Qlik.Engine.MethodInvocationException methodInvocationException)
                    {
                      // handle error
                    }
                  }
                } // using local, the license token will be released after 30 min.
              }
              catch (Qlik.Engine.Communication.CommunicationErrorException communicationException)
              {
                // handle error
              }

               

               

              Best regard

              Lars-Göran Book

                • Re: .NetSdk - Connection failed after 4 attempts
                  René Engler

                  Thank you for clarification.

                  • Re: .NetSdk - Connection failed after 4 attempts
                    lucas stiefel

                    Dear Lars-Goran,

                     

                    Sorry for re-opening this topic again. We've been trying to get this implemented in our app but we are still struggling with the Location not being disposed properly. In our case we are not able to create the location with "using" because actually the Qlik.Engine.Location class is not disposable.

                     

                    Is there any alternative for doing this? We have been trying removing the session via REST request or using different ways of connecting the location but it still returns the timeout after 5 connections one after the other.

                     

                    We will appreciate your help on this as we have been stuck for a few days already. Thank you!

                    Lucas Stiefel

                      • Re: .NetSdk - Connection failed after 4 attempts
                        Lars-Goran Book

                        Hi,

                        Which version of the SDK are you using? In the SDK version 2.x and 3.x have the Location have a Dispose method. In this Dispose method there is a REST call to do the logout. But be aware that the Proxy Session has a 5 min timeout which means that the session will be blocket for 5 min after dispose.
                        The best way to handle multiple calls is to keep the session alive all the time for example keeping it in a windows service.

                         

                        Best Regards

                        Lars-Göran Book

                          • Re: .NetSdk - Connection failed after 4 attempts
                            René Engler

                            Dear Lars-Goran,

                             

                            I don't understand why it's neccessary to block the sessions after dispose. Are there considerations to change this behaviour in future?

                             

                            Best regards

                            René Engler

                            • Re: .NetSdk - Connection failed after 4 attempts
                              Michal Pinka

                              Hi Lars-Göran,


                              Do you have any example how to keep the session alive using .NET?


                              Many thanks!


                              BRs,

                              Michal

                                • Re: .NetSdk - Connection failed after 4 attempts
                                  Øystein Kolsrud

                                  Do you mean you would like to use the SDK to avoid the "Session timed out" message in the client? If that is the case, then I think you could force that behavior by making sure you trigger some form of change notification that the client will react to. I experimented with a small loop that just updated the name of the app every now and then, and then I didn't get that time out. But you probably want to trigger some notification that doesn't really modify anything I guess. Perhaps you could do something with selections? Perhaps you could do some random selection and then do "app.Back()" to go back to the previous selection?

                                   

                                  You could also hook into the change notification of the app from the SDK and make sure you only do this operation only when needed.

                                    • Re: .NetSdk - Connection failed after 4 attempts
                                      Michal Pinka

                                      Hi Øystein,

                                       

                                      Thanks for your response!

                                       

                                      I'm working on the web page that loads data from sql tables to Qlik (i.e. change table name in the load script and reload). There is a dropdown list with available Qlik apps populated via Qlik API. When the user refreshes/posts the page the new proxy session is created. After 5 refreshes I get LicenseAccessDenied exception due to limit of 5 sessions. As I understand ILocastion.Dispose does not kill the session. I also tried to add REST call to logout but with no success. So I'm wondering how to terminate the session after each page load or to keep the session so the new one is not created each time.

                                       

                                      try

                                                  {

                                                      // Open location

                                                      using (ILocation location = Qlik.Engine.Location.FromUri(qlikConfig.QlikEngineUri))

                                                      {

                                                          // Define the location as a connection to Qlik Sense using NTLM Authentication

                                                          await location.AsNtlmUserViaProxyAsync();

                                                          // Add all available apps to the list                              

                                                          foreach (IAppIdentifier appIdentifier in await location.GetAppIdentifiersAsync())

                                                          {

                                                              apps.Add(new QlikApp() { Id = appIdentifier.AppId, Name = appIdentifier.AppName });

                                                          }

                                       

                                       

                                                          /* LOGOUT REST TEST */

                                                          var proxyPath = "";

                                                          if (!string.IsNullOrEmpty(location.VirtualProxyPath))

                                                          {

                                                              proxyPath += location.VirtualProxyPath + "/";

                                                          }

                                       

                                       

                                                          var serverPath = $"{location.ServerUri.AbsoluteUri}{proxyPath}";

                                                          var request = (HttpWebRequest)HttpWebRequest.Create($"{serverPath}qps/user");

                                       

                                       

                                                          //var request = (HttpWebRequest) HttpWebRequest.Create($"{location.ServerUri}qps/{proxyPath}session/{sessCookie[1]}");

                                                          //var reques = (HttpWebRequest)HttpWebRequest.Create(serverPat + "/user");

                                       

                                       

                                                          request.CookieContainer = new CookieContainer();

                                                          foreach (var cookie in location.CustomUserCookies)

                                                          {

                                                              request.CookieContainer.Add(new Uri(serverPath), new Cookie(cookie.Key, cookie.Value));

                                                          }

                                       

                                       

                                                          var sc = location.SessionCookie.Split('=');

                                                          request.CookieContainer.Add(new Uri(serverPath), new Cookie(sc[0], sc[1]));

                                                          request.Method = "DELETE";

                                                          var res = request.GetResponse();

                                                      }

                                                  }

                                       

                                      Many thanks!

                                       

                                      BRs,

                                      m