PLUSManaged: Cloud-Controlled Network Floating Licensing using SOLO Server

Network Floating Licensing is where an application may be restricted to running on a specific network, and restricted to a certain number of concurrent seats (where a seat may be a user or running instance of your application). This topic guides you through some basics of getting started with using Cloud-Controlled Network Floating Licensing using SOLO Server. This feature has some limitations, so it is very important to review the overview of network floating before using it.

Important

Note that the Cloud-Controlled Network Floating Licensing using SOLO Server is only supported in Windows platforms. See the overview of network floating for additional details.

If you wish to use Cloud-Controlled Network Floating Licensing using SOLO Server, you will need to contact us for additional details on availability and pricing.

Getting Started

To begin, use/import the necessary namespaces to your relevant source file(s).  This is typically added to your application's primary form, or where your primary application start-up logic is located.

C#
using com.softwarekey.Client.Licensing;
using com.softwarekey.Client.Licensing.Network;
using com.softwarekey.Client.Utils;
using com.softwarekey.Client.WebService.XmlNetworkFloatingService;
VB.NET
Imports com.softwarekey.Client.Licensing
Imports com.softwarekey.Client.Licensing.Network
Imports com.softwarekey.Client.Utils
Imports com.softwarekey.Client.WebService.XmlNetworkFloatingService

Next, you'll need to add a member variable for the network session, and some static configuration properties.

C#
private NetworkSession _Session = null;
//TODO: Adjust the certificate path as needed.
private static string _CertificatePath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "Session.xml");

//TODO: Adjust this to use your SOLO Server account's encryption key data.
private static AuthorEncryptionKey EncryptionKey
{
get { return new AuthorEncryptionKey("[Your Envelope Key from SOLO Server", "Your Envelope from SOLO Server", false); }
}

//TODO: Adjust the algorithms selected to suit your needs.
private static List<SystemIdentifierAlgorithm> SystemIdentifierAlgorithms
{
get
{
return new List<SystemIdentifierAlgorithm>(new SystemIdentifierAlgorithm[] {
new HardDiskVolumeSerialIdentifierAlgorithm(HardDiskVolumeSerialFilterType.OperatingSystemRootVolume),
new NicIdentifierAlgorithm(),
new ComputerNameIdentifierAlgorithm() });
}
}
VB.NET
Private _Session As NetworkSession = Nothing
'TODO: Adjust the certificate path as needed.
Private Shared _CertificatePath As String = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "Session.xml")

'TODO: Adjust this to use your SOLO Server account's encryption key data.
Private Shared ReadOnly Property EncryptionKey() As AuthorEncryptionKey
Get
Return New AuthorEncryptionKey("[Your Envelope Key from SOLO Server", "Your Envelope from SOLO Server", False)
End Get
End Property

'TODO: Adjust the algorithms selected to suit your needs.
Private Shared ReadOnly Property SystemIdentifierAlgorithms() As List(Of SystemIdentifierAlgorithm)
Get
Return New List(Of SystemIdentifierAlgorithm)(New SystemIdentifierAlgorithm() {New NicIdentifierAlgorithm(), _
New HardDiskVolumeSerialIdentifierAlgorithm(HardDiskVolumeSerialFilterType.OperatingSystemRootVolume), _
New ComputerNameIdentifierAlgorithm()})
End Get
End Property

Note that the samples include encryption envelopes that are linked to the SOLO Server test account. You can either use the test credentials, or you can retrieve the encryption key data for your account, even if you are currently evaluating SOLO Server.

Opening a Session

Opening a session is synonymous with attempting to allocate a seat, which is only allowed to occur if the seats are not already consumed by other users and/or application instances. A rough example of the contents of a function that opens a session is shown below.

C#
_Session = new NetworkSession(EncryptionKey, true, true, SystemIdentifierAlgorithms, _CertificatePath, false);
if (_Session.OpenSession([LicenseID], "[Customer Password]"))
{
//TODO: Session opened successfully - add additional logic here to update your dialog's controls.
}
else
{
//TODO: Handle error condition. Show an error message to the user with details from _Session.LastError.
}
VB.NET
_Session = new NetworkSession(EncryptionKey, True, True, SystemIdentifierAlgorithms, _CertificatePath, False)
If _Session.OpenSession([LicenseID], "[Customer Password]") Then
'TODO: Session opened successfully - add additional logic here to update your dialog's controls.
Else
'TODO: Handle error condition. Show an error message to the user with details from _Session.LastError.
End If

Upon opening a session, you receive a network session certificate, which contains data about the session and how the protected application should behave. For example, it contains the date and time the session expires, whether or not it has been checked-out, how long it should wait between poll attempts, and more. In the example above, the data is available in properties under the _Session.Certificate property.

Validating a Session

Once a session is open, and immediately after any action (other than closing the session) is performed, it is necessary to validate the session.  The example below shows how you can use the NetworkSessionValidation class, which is included with PLUSManaged to simplify the validation process.

C#
NetworkSessionValidation validation = new NetworkSessionValidation(_Session);
if (validation.Validate())
{
//TODO: Your session is valid. Update controls as appropriate.
}
else
{
//TODO: Notify the user that the session is no longer valid, update controls as appropriate, and include details from validation.LastError.
//TODO: Close the session if it is already open.
}
VB.NET
Dim validation As New NetworkSessionValidation(_Session)
If validation.Validate() Then
'TODO: Your session is valid. Update controls as appropriate.
Else
'TODO: Notify the user that the session is no longer valid, update controls as appropriate, and include details from validation.LastError.
'TODO: Close the session if it is already open.
End If

Note that it is important to close the session rather than abandoning it when validation fails. This is because the session should not be allowed to be used when invalid, and if the session remains open on SOLO Server even though local validation has failed, abandoning it will cause SOLO Server to consider the seat to be valid until the allocated until date (or the date and time the session is set to expire if it has not polled successfully before then).

Polling a Session

When a session is open, it is set to expire by its "allocated until date."  In other words, if no poll occurs before the date and time shown in the "allocated until date" is reached, the session is considered expired by SOLO Server. Successfully polling the session with SOLO Server automatically extends the allocated until date, which is what allows SOLO Server to recover orphaned sessions/seats (which is helpful for handling abnormal application termination).

C#
if (_Session.Poll())
{
//TODO: The poll was successful.  Re-validate the session and update controls as needed.
}
else
{
//TODO: The poll failed.  Show an error message and close the session.
}
VB.NET
If _Session.Poll() Then
'TODO: The poll was successful.  Re-validate the session and update controls as needed.
Else
'TODO: The poll failed.  Show an error message and close the session.
End If

If a session has been checked-out for extended/offline use, you may still poll to verify the session if Internet connectivity is available. However, the "allocated until date" is not automatically extended for a checked-out session.

Checking-out and Checking-in a Session

In some cases, you may find the need to allow users to check-out a session/seat for offline and/or extended use. An example could be a user who needs to use the protected application while traveling. To allow this, you can allow the user to check-out a session for a requested duration. When successful, SOLO Server will respond with an updated session certificate that has an allocated until date that is valid for the requested duration (or until the minimum or maximum check-out duration allowed if the requested duration is outside of those bounds).

C#
if (!_Session.Certificate.CheckedOut)
{
//TODO: The session is already checked-out; optionally show an error message.
return;
}

if (_Session.CheckoutSession([requestedCheckoutDuration]))
{
//TODO: The session was checked-out successfully.  Re-validate the session and update controls as needed.
}
else
{
//TODO: The session could not be checked-out. Show an error message including details from _Session.LastError.
}
VB.NET
If _Session.Certificate.CheckedOut Then
'TODO: The session is already checked-out; optionally show an error message.
Return
End If

If _Session.CheckoutSession([requestedCheckoutDuration]) Then
'TODO: The session was checked-out successfully.  Re-validate the session and update controls as needed.
Else
'TODO: The check-out failed.  Show an error message including details from _Session.LastError.
End If

Once checked-out, your application may continue to poll when Internet connectivity is available (just keep in mind that attempting to poll while offline could cause performance degradation). The seat will then be consumed until the allocated until date is reached, or the user checks-in and closes the session. So in the example of a traveling user, you might allow the user to check-out for up to a week, even though the user is only expected to travel for 3 to 4 days. This allows the user to continue to use the application in a disconnected state should unforeseen circumstances (such as inclement weather) arise. If the user returns when expected, he or she could then check-in the session and return to normal connected use so the seat becomes available for other users when not in use.

C#
if (!_Session.Certificate.CheckedOut)
{
//TODO: The session is not checked-out; optionally show an error message.
return;
}

if (_Session.CheckinSession())
{
//TODO: The session was checked-in successfully.  Re-validate the session, and update controls as needed.
}
else
{
//TODO: The session could not be checked-in. Show an error message including details from _Session.LastError.
}
VB.NET
If Not _Session.Certificate.CheckedOut Then
'TODO: The session is not checked-out; optionally show an error message.
Return
End If

If _Session.CheckinSession() Then
'TODO: The session was checked-in successfully.  Re-validate the session, and update controls as needed.
Else
'TODO: The session could not be checked-in.  Show an error message including details from _Session.LastError.
End If

Once the session has been checked-in, it may resume normal connected use with periodic polls. Otherwise, the session should be closed if the session is no longer being used actively.

Closing a Session

A session should be closed any time it is no longer being used by the user, or any time it fails local validation. This helps ensure it the seat that was previously in use becomes free for other users to open and use.

C#
if (_Session.Close())
{
//TODO: The session was closed successfully.  Update controls as needed.
}
else
{
//TODO: The session could not be closed. Show an error message including details from _Session.LastError, and close the session.
}
VB.NET
If _Session.Close() Then
'TODO: The session was closed successfully.  Update controls as needed.
Else
'TODO: The session could not be closed. Show an error message including details from _Session.LastError, and close the session.
End If

Review the Sample

The example code excerpts given above are only meant to provide guidance on how the APIs should be used. Review the PLUSManaged samples to see complete, functioning example code that can be re-used in your applications.