# Floating Server Usage

Distributing software applications designed for closed networks comes with numerous obstacles.

Challenges include implementing node locking on virtual machines and activating licenses meant for devices with strict security demands, often in the absence of internet connectivity.

LicenseSpring provides a solution through a [**Floating License Server**](https://docs.licensespring.com/license-entitlements/floating-licenses/floating-license-server). This server can be set up and customized at your customers' locations, ensuring functionality even when the client application runs on a machine without internet access.

LicenseSpring's offerings encompass both a floating server tailored for private networks and a cloud-based floating license solution. The client SDK functions quite similarly in both situations.

To learn more about the processes of registering, deregistering, managing timeouts, and borrowing licenses using a cloud-based floating license, see [**Floating Licensing**](https://docs.licensespring.com/sdks/tutorials/licensing-scenarios/floating-licensing).

### Floating Client Identifier

The floating client or instance identifier can be accessed through a `License` object by using:

{% tabs %}
{% tab title="C++" %}

```cpp
string floatingClientID = license->floatingClientId();
```

{% endtab %}

{% tab title="C#" %}

```csharp
string floatingClientID = license.FloatingClientId();
```

{% endtab %}

{% tab title="Swift" %}

```swift
if let id = license.floatingClientID { ... }
```

{% endtab %}

{% tab title="Python" %}

```python
client_id = license.floating_client_id()

print(client_id)
```

{% endtab %}
{% endtabs %}

This floating client identifier is set during registration, within the `register` method shown below.

### Floating Client

The `FloatingClient` class is used to perform requests to LicenseSpring's floating server. Within a `FloatingClient` object, developers are able to:

* Register and unregister clients.
* Borrow licenses.\*
* Retrieve server information.
* Check whether the connection to the floating server is online.

\*Only offered in C++ SDK

#### Registering a Client

Developers register clients with the following method:

{% tabs %}
{% tab title="C++" %}

```cpp
License license = floatingClient->registerLicense( id, licenseID );
```

{% endtab %}

{% tab title="Swift" %}

```swift
let floatingClient = FloatingClient(configuration: configuration)
let license = try floatingClient.register(userID: "user id")
```

{% endtab %}

{% tab title="Python" %}

```python
#floating client
from licensespring.floating_server import FloatingAPIClient

api_client = FloatingAPIClient(api_protocol="http", api_domain="localhost:8080")

response = api_client.register_user(
    product="lkprod1",
    user="user_1",
    os_hostname="bla",
    ip_local="bla",
    user_info="bla",
    license_id=1728377159207169
)

print(response)

#floating manager
from licensespring.licensefile.config import Configuration
from licensespring.licensefile.floating_manager import FloatingManager

conf = Configuration(
    product=product,
    api_key="arbitrary",
    shared_key="arbitrary",
    file_key="your_file_key",
    file_iv="your_file_iv",
    api_domain="api_domain",
    api_protocol="http/https",
)

fs_manager = FloatingManager(conf=conf)
license = fs_manager.register()
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Note: `id` is the user or instance id used for license registration, it can be anything: email, hostname, handle, etc.

`licenseID` is an optional parameter where a specific license identifier can be specified. If no parameter is provided, the license gets the default configuration for the product.
{% endhint %}

If registration is successful, a shared pointer to the `License` object is returned. If unsuccessful, an exception is thrown.

#### Unregistering a Client

The unregister method uses the exact same parameters as register:

{% tabs %}
{% tab title="C++" %}

```cpp
bool unregistered = floatingClient->unregisterLicense( id, licenseID );
```

{% endtab %}

{% tab title="C#" %}

```csharp
bool unregistered = floatingClient.Unregister( id, licenseID );
```

{% endtab %}

{% tab title="Swift" %}

```swift
try floatingClient.unregister(userID: "user id")
```

{% endtab %}

{% tab title="Python" %}

```python
#floating client
from licensespring.floating_server import FloatingAPIClient

response = api_client.unregister_user(product="lkprod1",user="user_1",license_id=1728377159207169)

print(response)

#floating manager
from licensespring.licensefile.config import Configuration
from licensespring.licensefile.floating_manager import FloatingManager

conf = Configuration(
    product=product,
    api_key="arbitrary",
    shared_key="arbitrary",
    file_key="your_file_key",
    file_iv="your_file_iv",
    api_domain="api_domain",
    api_protocol="http/https",
)

fs_manager = FloatingManager(conf=conf)
# There are multiple options to unregister a license
# 1. floating client -> this one is documanted
fs_manager.unregister()
# 2.1. license object -> deactivate method
license.deactivate() 
#2.2 license object -> floating release
license.floating_release(False)
```

{% endtab %}
{% endtabs %}

This Boolean result is set to true if the client was unregistered successfully.

#### License Borrowing

Only available in the C++ SDK, the following method allows developers to register and borrow licenses at once:

{% tabs %}
{% tab title="C++" %}

```cpp
License license = floatingClient->borrowLicense( id, borrowEndDateTime );
```

{% endtab %}

{% tab title="Swift" %}

```swift
try license.borrow(for: 24 * 60 * 60) // 1 day.
```

{% endtab %}

{% tab title="Python" %}

```python
# floating client
from licensespring.floating_server import FloatingAPIClient

api_client = FloatingAPIClient(api_protocol="http", api_domain="localhost:8080")

response = api_client.borrow(
        product="lkprod1",
        user="user_1",
        borrowed_until="2029-05-06T00:00:00Z",
        os_hostname="bla",
        ip_local="bla",
        user_info="bla",
        license_id=1728377159207169,
    )

# floating manager
from licensespring.licensefile.config import Configuration
from licensespring.licensefile.floating_manager import FloatingManager

conf = Configuration(
    product=product,
    api_key="arbitrary",
    shared_key="arbitrary",
    file_key="your_file_key",
    file_iv="your_file_iv",
    api_domain="api_domain",
    api_protocol="http/https",
)

fs_manager = FloatingManager(conf=conf)
license = fs_manager.borrow("2031-05-06T00:00:00Z")
# borrow can be also used within the License object
license.floating_borrow("2031-05-06T00:00:00Z")
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Note: The `id` parameter is the user or instance identifier used for license registration. `borrowEndDateTime` is the borrow end date time in format "%Y-%m-%dT%H:%M:%SZ", for example "2022-05-28T15:30:00Z".
{% endhint %}

{% hint style="danger" %}
`borrowLicense()` can throw the same exceptions as on registration and License::borrow, see those methods for more details.
{% endhint %}

For more information about license borrowing, see [**Floating Licensing**](https://docs.licensespring.com/sdks/tutorials/licensing-scenarios/floating-licensing).

#### Floating Server and License Information

A helper method for checking the connection the floating server is provided within the `FloatingClient` object:

{% tabs %}
{% tab title="C++" %}

```cpp
bool online = floatingClient->isOnline();
```

{% endtab %}

{% tab title="C#" %}

```csharp
bool online = floatingClient.IsOnline();
```

{% endtab %}

{% tab title="Swift" %}

```swift
let online: Bool = floatingClient.checkConnection()
```

{% endtab %}

{% tab title="Python" %}

```python
from licensespring.licensefile.config import Configuration
from licensespring.licensefile.floating_manager import FloatingManager

conf = Configuration(
    product=product,
    api_key="arbitrary",
    shared_key="arbitrary",
    file_key="your_file_key",
    file_iv="your_file_iv",
    api_domain="api_domain",
    api_protocol="http/https",
)

fs_manager = FloatingManager(conf=conf)
response = fs_manager.is_online()
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Note: `isOnline()` methods have an optional parameter, `throwExceptions`, that indicates whether the method should throw exceptions.
{% endhint %}

Using the `FloatingClient` object, developers are also able to access a `FloatingServerInfo` object with:

{% tabs %}
{% tab title="C++" %}

```cpp
FloatingServerInfo floatingServerInfo = floatingClient->getServerInfo();
```

{% endtab %}

{% tab title="C#" %}

```csharp
FloatingServerInfo floatingServerInfo = floatingClient.GetServerInfo();
```

{% endtab %}
{% endtabs %}

`FloatingServerInfo` consists of:

* `RegistrationExpiry` - The floating server registration expiry in minutes.
* `Servers` - The list of floating server IP addresses available in the network.

In the .NET SDK, it is also possible to get the license information for a configured product with:

```csharp
License license = floatingClient.GetLicenseInfo();
```

{% hint style="info" %}
Note: There is an optional parameter for `GetLicenseInfo()`, where a specific license identifier can be specified. If no parameter is provided, the license gets the default configuration for the product.
{% endhint %}

See [**Get license**](https://docs.licensespring.com/floating-server/floating-server-v1/api-reference/license/get-license) for more information.
