1. Set a concurrent seat limit
For a company with 100 computers and 10 concurrent seats, choose the floating authorization mode and set its concurrency limit to 10. This limits active sessions; it is different from node-locked device registration.
Set the heartbeat interval and session lease together. The lease must exceed the heartbeat interval plus its maximum jitter and a 30-second margin. A short lease recovers abandoned seats sooner but tolerates less network disruption.
2. Acquire a seat at startup
Install your SDK from the website and open one client using product.json and the customer's license key. Floating startup must receive online authorization; a saved offline cache is not a substitute for acquiring a session.
The following Go fragment belongs in an application function returning error. It needs context, os, os/signal and log imports. exportReport is your existing business callback; customerKey comes from the activation form.
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()
client, err := licentivo.OpenWithLicense(ctx, "product.json", customerKey,
func(err error) { log.Printf("License refresh: %v", err) })
if err != nil {
return err // Show an activation error; do not start protected work.
}
defer client.Close() // Attempts to return a floating seat.
// Place this check inside each protected action, not only at startup.
if err := client.RunFeature("export", exportReport); err != nil {
return err
}
<-ctx.Done()3. Let the SDK schedule heartbeats
Do not write your own timer or send parallel HTTP heartbeat requests. The SDK uses the authorized interval and renews the session. Keep the client alive while the application is running.
Place RunFeature in every protected handler. If a check is denied, stop that protected action and show a licensing message. Display useful background connection errors; do not assume a startup check permanently authorizes later operations.
An expired lease, revoked license or seat denial is handled by the signed authorization rules. Reconnecting requires a successful server check. Never extend a session by editing local expiry data.
4. Release on a normal exit
Close the client on a normal exit. Go uses defer client.Close(); Java and C# have scoped disposal, C++ and Rust use destruction, Python uses its context manager, and Ruby/JavaScript expose close.
If the application crashes or cannot contact the server during shutdown, the server reclaims the abandoned seat when its session lease expires. That delay is expected; keep a clear message so another user understands when a seat may become available.
5. Test with two separate machines
- Set a test license to one floating seat. Start the application on computer A.
- Start on computer B: the second protected session should be denied while A holds the seat.
- Exit A normally, then verify B can acquire a seat.
- In the isolated test environment, stop A without cleanup; verify the seat returns after the configured lease expires.
Troubleshooting seat conflicts
Node-locked and floating modes have different exit behavior: node-locked shutdown keeps registration, while floating shutdown tries to return a seat. Do not call device unbind every time a node-locked application closes.
A seat-in-use message can be caused by another running instance or a recently crashed process waiting for lease expiry. Review current sessions in the console before increasing the purchased seat count.
File-based first activation is for node-locked licenses. Metered operations still require online reserve and settle calls even when the floating session itself is valid.