Skip to main content

Integration, Extension & APIs

Discussion board where members can learn more about Integration, Extensions and API’s for Qlik Sense.

Announcements
CUSTOMERS ONLY: Now accepting customer applications for the 2023 Luminary Program: SUBMIT NOW
cancel
Showing results for 
Search instead for 
Did you mean: 
geetika_garg01
Contributor II
Contributor II

'App already open' error in Qlik Sense Engine API

We are trying to fetch Qlik Sense object level information using Engine APIs with Java websockets. We are able to make connection to qlik server and get list of all App ids. But when we try to get sheet level information(thro opendoc and getlayout methods) for all apps fetched, code gets stuck to first app and doesn’t give sheet level information for other apps giving error “App already open”. Looks like we need to disconnect the first app after fetching sheet level information and then move to next app. Issue is that there is no direct way to disconnect an app which is open using Engine APIs. If you have any idea how to resolve this issue then please let us know.

11 Replies
ErikWetterberg

‌Hi,

you should open a new web socket for each dokument. The only way to close the app connection is to close the socket.

Erik Wetterberg

nate_muir_anderson
Contributor II
Contributor II

Your other answer helped me!

https://community.qlik.com/t5/Qlik-Sense-Integration/Qlik-server-stuck-at-SESSION-ATTACHED-stage/td-...

 

I did this, and the "App already open" error, stopped


@geetika_garg01 wrote:

we realized that we needed to append the Qlik app ID to the Engine API URLs when making our WebSocket connections to get an isolated Qlik Engine session for each Qlik app.




SaturnV
Partner - Contributor III
Partner - Contributor III

Hi,

I know this is maybe a bit late, but I am running into an additional problem, by opening a new session (websocket) for each app. The Session Limit of Qlik is 5. So after 5 apps I cant proceed with other apps. And as you already know, you cant open multiple apps in one Session ("App already open"). So how do you do it?

Thanks and best regards

Julian

Øystein_Kolsrud
Employee
Employee

The key here is that there is a difference between engine sessions and proxy sessions. It is the proxy sessions that has the  5 session limit, not the engine. So if you reuse the same proxy session between the websocket connections, then you should be able to open multiple apps. Reusing the proxy session is a matter of setting the right cookie I believe. You nee to take the session cookie you get from your first connection an add it to the other connections you make.

SaturnV
Partner - Contributor III
Partner - Contributor III

Hi @Øystein_Kolsrud,

thank you for the answer. I am programming a .exe in C#. So not via the Browser. These are the 2 Responsemessages I receive on connecting to the Engine API:

ResponseMessage 1: {"jsonrpc":"2.0","method":"OnAuthenticationInformation","params":{"userId":"username","userDirectory":"LAB","logoutUri":"https://ctlab-qsm01.lab.local.lan/testvpjd/qps/user","serverNodeId":"587491ba-a63c-4928-b814-1252ace...}}

ResponseMessage 2: {"jsonrpc":"2.0","method":"OnConnected","params":{"qSessionState":"SESSION_CREATED"}}

So how to add which parameter to the next connection?
An additional Header with which information?
Is this even possible withing a non browser application?

Best regards

Julian

Øystein_Kolsrud
Employee
Employee

The session cookie is not passed as part of the websocket communication, but is set up during the handshake that establishes the connection. Are you using the the .NET SDK for your solution? In that case it should be sufficient for you to simply reuse the Location instance as it keeps track of the cookies. So instead of doing this:

 

foreach (var appId in appIds)
{
    var location = Location.FromUri(url);
    location.AsNtlmUserViaProxy();
    using (var app = location.App(appId))
    {
        DoStuff();
    }
}

 

You should do this:

 

var location = Location.FromUri(url);
location.AsNtlmUserViaProxy();
foreach (var appId in appIds)
{
    using (var app = location.App(appId))
    {
        DoStuff();
    }
}

 

 

SaturnV
Partner - Contributor III
Partner - Contributor III

Unfortunately I am not using the .NET SDK. I am unsing the ClientWebsocket class (System.Net.Websockets).

I am using the Methods ClientWebsocket.ConnectAsync(), ClientWebsocket.SendAsync() and ClientWebSocket.ReceiveAsync()

Is there a way to get the cookie anyways? Maybe via the Headers with ClientWebsocket.Options.SetRequestHeader?

Øystein_Kolsrud
Employee
Employee

I think you need to add the cookie to the cookie jar here:

theSocket.Options.Cookies

I'm not sure if that is sufficient though. Getting all those authentication settings right can be rather tricky when operating at a low level like that. Documentation for the Cookies property can be found here: https://docs.microsoft.com/en-us/dotnet/api/system.net.websockets.clientwebsocketoptions.cookies?vie...

 

Damien_Villaret
Support
Support

Hello @SaturnV 

I guess that could as well work by setting the header "Cookie" in the same way it's done in the enigma.js example below:

https://support.qlik.com/articles/000077843

If the issue is solved please mark the answer with Accept as Solution.