API detect unexpected client disconnection

Hiya,

What is the correct way to catch the unexpected/unclean removal of an API client form a server app?

Use case:

I have a server app that publishes an API.

When a client connects to the API (say using api_Open()), certain resources are locked by the server for the exclusive use of that client.

When the client closes cleanly, it should call api_Close() to indicate to the server that the resources are no longer required by the client and can be released for use by another client.

I need to trap the case where the client faults or otherwise exits without calling api_Close() so that the server can release the locked resources.

How can this be done?

Thanks, Dave

Hi David,

You need to create an event handler in the server side that will be called when a client application is terminated. Then, inside the event handler, you may clean the allocated resources properly.

To do so, first add a handler in the COMPONENT_INIT of your server:
le_msg_AddServiceCloseHandler(api_GetServiceRef(), CloseSessionEventHandler, NULL);

Then, inside the close session event handler, clean the allocated resources. You may need to add an extra field along with the resources to save the client reference when api_Open() is called. The event handler looks like this:

static void CloseSessionEventHandler
(
    le_msg_SessionRef_t sessionRef, ///< [IN] Message session reference.
    void* contextPtr                ///< [IN] Context pointer.
)
{
    if (!sessionRef)
    {
        LE_ERROR("ERROR sessionRef is NULL");
        return;
    }

    LE_DEBUG("SessionRef (%p) has been closed", sessionRef);
    //Clean resources allocated by this client
}

Hope this helps,
Regards,

Hi @oabid

Thanks. Much appreciated.

I’ll give it a go.

I assume that I can store the data reference I create when a component open()'s my service in the context of le_msg_AddServiceCloseHandler()?

ciao, Dave

Yes, it is possible to have the app client reference when it calls a server API. The function is called: api_GetClientSessioRef();