Scanner Driver
The SDK communicates with fingerprint scanners through a local WebSocket driver. The DriverSocket class manages the connection, automatic reconnection, and event dispatching.
Architecture
The local driver runs as a local service on the user's machine and exposes a WebSocket endpoint at wss://local.heuristik.com:2794/hk-reader. The SDK connects to this endpoint automatically when the client is created.
Connection lifecycle
On construction, DriverSocket attempts to connect. If the connection drops, it reconnects with exponential backoff. Calling destroy() terminates the connection permanently.
Exponential backoff
When the connection drops, the driver reconnects with exponential backoff:
| Attempt | Delay |
|---|---|
| 1 | 2s |
| 2 | 4s |
| 3 | 8s |
| 4 | 16s |
| 5+ | 32s (capped at 60s) |
Events
The DriverSocket emits the following events via its internal EventEmitter:
| Event | Payload | Description |
|---|---|---|
connected | driverId: string | WebSocket connection established |
disconnected | driverId: string | WebSocket connection lost |
sensorConnected | DeviceDescription.data | Scanner device detected and described |
sensorDisconnected | deviceId?: number | Scanner device lost |
fingerprintPreview | base64Image: string | Preview frame from scanner (BMP) |
fingerprintResult | base64Image: string, score?: number, deviceId?: number | Final result with quality score |
Sensor and driver status
To check the status of both the sensor and the driver service, four methods are available for listening to connection/disconnection events: onSensorConnected, onSensorDisconnected, onDriverConnected, onDriverDisconnected.
By listening to these events, it is possible to capture when the sensor and/or driver connects or disconnects (as well as verify the initial state) and take appropriate action.
Functions getCurrentSensor() or getConnectedSensors() also provide information about the sensor in use.
const sensorConnectedHandler = (device) => {
const serialNumber = device.serialNumber ?? 'S/N unknown';
const hardwareVersion = device.hardwareVersion ?? '-';
const firmwareVersion = device.firmwareVersion ?? '-';
console.log(`Sensor connected: ${serialNumber}; Hardware: ${hardwareVersion}; Firmware: ${firmwareVersion}`);
}
const sensorDisconnectedHandler = (deviceId, serialNumber) => {
console.log(
typeof deviceId === 'number'
? `Sensor disconnected (device_id=${deviceId}; serial_number: ${serialNumber})`
: `Sensor disconnected`
)
}
const driverConnectedHandler = (driverId) => {
console.log(`Driver connected. ${driverId ? `Driver Id: ${driverId}` : ''}`);
const currentSensor = client.operations.getCurrentSensor() || client.operations.getConnectedSensors()[0];
if (currentSensor) {
sensorConnectedHandler(currentSensor);
} else {
console.log('Not sensor available');
}
}
const driverDisconnectedHandler = (driverId) => {
console.log(`Driver disconnected. ${driverId ? `Driver Id: ${driverId}` : ''}`);
console.log('Sensor connection lost because driver disconnection');
}
client.operations.onSensorConnected(sensorConnectedHandler);
client.operations.onSensorDisconnected(sensorDisconnectedHandler);
client.operations.onDriverConnected(driverConnectedHandler);
client.operations.onDriverDisconnected(driverDisconnectedHandler);
To cancel your subscription to events, you can use the corresponding offSensorConnected, offSensorDisconnected, offDriverConnected y offDriverDisconnected.
client.operations.offSensorConnected(sensorConnectedHandler);
client.operations.offSensorDisconneted(sensorDisconnectedHandler);
client.operations.offDriverConnected(driverConnectedHandler);
client.operations.offDriverDisconnected(driverDisconnectedHandler);