IoT & Tracking
Build real-time IoT applications and tracking systems with NoLag.
Overview
NoLag is ideal for IoT applications that require real-time data streaming from devices. Whether you're tracking vehicles, monitoring sensors, or controlling smart devices, NoLag provides the low-latency infrastructure you need.
App Setup
Rooms never exist implicitly, so create the app, its room, and its actors before any device or dashboard connects. Give each vehicle its own device actor and the dashboard its own user actor: publishers never receive their own messages, so a dashboard that reused a device's token would never see that device's updates.
import { NoLagApi } from '@nolag/js-sdk'
const api = new NoLagApi(process.env.NOLAG_API_KEY) // nlg_live_...
// 1. Create the app and declare the topics it allows. The slug that comes back
// has a random suffix, so read it from the response.
const app = await api.apps.create({
name: 'Fleet Tracker',
slug: 'fleet-tracker',
topics: ['location', 'telemetry'],
})
console.log(app.slug) // e.g. "fleet-tracker-a3f9": this is your APP_SLUG
// 2. Create the room. Room slugs are kept exactly as you supply them.
await api.rooms.create(app.appId, { name: 'Vehicles', slug: 'vehicles' })
// 3. One device actor per vehicle, and a user actor for the dashboard.
// Each access token is shown once; keep them.
const truck42 = await api.actors.create({ name: 'truck-42', actorType: 'device', externalId: 'truck-42' })
const dashboard = await api.actors.create({ name: 'fleet-dashboard', actorType: 'user' })
console.log(truck42.accessToken, dashboard.accessToken)Fleet Tracking Example
The dashboard connects with its user actor and subscribes to every vehicle's updates in the vehicles room.
import { NoLag } from '@nolag/js-sdk'
const APP_SLUG = 'fleet-tracker-a3f9' // the slug returned when you created the app
interface Location {
vehicleId: string
latitude: number
longitude: number
heading: number
speed: number
timestamp: number
}
interface Telemetry {
vehicleId: string
fuelLevel: number
engineStatus: string
batteryVoltage: number
}
const client = NoLag('dashboard_access_token')
client.on('error', (err) => console.error(err)) // unknown_topic etc. arrive here
await client.connect()
const fleet = client.setApp(APP_SLUG).setRoom('vehicles')
// Subscribe to all vehicle updates
fleet.subscribe('location')
fleet.subscribe('telemetry')
// Handle location updates. Payloads arrive as `unknown`; name the shape you expect.
fleet.on<Location>('location', (data) => {
updateMapMarker(data.vehicleId, {
lat: data.latitude,
lng: data.longitude,
heading: data.heading,
speed: data.speed
})
})
// Handle telemetry data
fleet.on<Telemetry>('telemetry', (data) => {
updateVehicleStatus(data.vehicleId, {
fuel: data.fuelLevel,
engine: data.engineStatus,
battery: data.batteryVoltage
})
})Device Publishing
On the IoT device, connect with that device's own actor and publish updates at regular intervals:
import { NoLag } from '@nolag/js-sdk'
const APP_SLUG = 'fleet-tracker-a3f9' // the slug returned when you created the app
const DEVICE_ID = 'truck-42'
// On the IoT device: its own device actor
const client = NoLag('truck_42_access_token')
await client.connect()
const device = client.setApp(APP_SLUG).setRoom('vehicles')
// Publish location updates every 5 seconds
setInterval(() => {
const location = gps.getLocation()
device.emit('location', {
vehicleId: DEVICE_ID,
latitude: location.lat,
longitude: location.lng,
heading: location.heading,
speed: location.speed,
timestamp: Date.now()
})
}, 5000)Use Cases
- Fleet management - Track vehicles, deliveries, and drivers
- Asset tracking - Monitor equipment and inventory location
- Sensor networks - Collect data from environmental sensors
- Smart home - Control and monitor IoT devices
- Wearables - Stream health and fitness data
Best Practices
- Use one
deviceactor per device, and a separate actor for anything that needs to see what the devices publish - Batch telemetry data to reduce message frequency; the broker accepts 50 publishes per second per connection
- QoS 1, the default, acknowledges each publish on the broker hop. It is not an end-to-end guarantee, so deduplicate on a reading's timestamp if a message must not be applied twice. See Quality of Service
- Reconnection is built in. Every SDK reconnects automatically after a drop (
reconnectdefaults to true) and the broker restores the connection's subscriptions. Tune the cadence for unreliable networks instead of writing your own loop:reconnectIntervalin JavaScript (milliseconds, with backoff up to 30 seconds),reconnect_intervalandmax_reconnect_attemptsin Python,ReconnectIntervalandMaxReconnectAttemptsin Go (-1retries forever). The default is 5 seconds and 10 attempts - Consider data retention and historical storage needs. NoLag delivers live readings and does not keep a history for you; a trigger webhook receives every publish and can write it to your own store