Introduction
Before proceeding, please take a moment to register an account with NoLag. This will make it easier to follow along.
To stay up-to-date with future updates and get help, we encourage you to join our Discord server.
How to use this developer docs?
Our developer docs are designed to be used sequentially.
- First, take a look at the Quick example section to see what NoLag can be used for and view some example code.
- Next, follow the steps in the Getting Started section for an overview of how to use NoLag.
- Then, dive into the Client SDK section to learn more about the technical details of using NoLag.
- Finally, explore the API section to gain access to NoLag's public resources.
Why NoLag?
NoLag provides a seamless plug-and-play solution that enables real-time communication between devices on any computer system.
At its core, NoLag is a Pub/Sub message broker with a variety of additional features.
What sets NoLag apart from other similar services:
- The ability to use NQL (NoLag Query Language) for targeted message delivery. With NQL, you have greater control over who receives which message and from which device.
- The single access security token manages access to tunnels, Pub/Sub access levels, and locked topics.
- Very low latency (Lag)
In summary, NoLag offers more fine-grained control over message delivery, device management and security, making it a unique and powerful tool for real-time communication.
Supported languages
On the right, you'll find a list of language flavors. You can use the package manager commands listed to install the NoLag SDK.
If you're interested in creating your own integration, be sure to check out the NoLag Transfer Protocol section.
We support
npm i nolagjs
yarn add nolagjs
Quick Example
Assuming you've already created a tunnel with topics and obtained a device token.
Integrating NoLag into your application is a quick and easy process.
Check out NoLag in action, we created a few industry demo examples.
/**
* ----- Create NoLag Tunnel connection -----
* */
import {
WebSocketClient,
stringToArrayBuffer,
uint8ArrayToString,
} from "nolag";
import type { ITopic, ITunnel, IResponse } from "nolag";
const accessToken: string = "<your_access_token_goes_here>";
const nolagInstance: ITunnel = await WebSocketClient(accessToken);
/**
* ----- SUBSCRIBE to Topic and set some identifiers to listen to -----
*/
const rideShareDriver: ITopic = nolagInstance.subscribe("rideShareDriver", [
"fleetOne",
"southEast",
]);
/**
* ----- PUBLISH some data to a topic and grouping of identifiers -----
*/
const rideShareDriver: string = JSON.stringify({
driverId: "6a9d03f5-bc0f-4516-9b51-c223a6cac0d2",
driverCurrentLocation: {
lat: "1234",
lng: "34564",
},
});
// payload as ArrayBuffer
const payloadArrayBuffer: ArrayBuffer = stringToArrayBuffer(payload);
// identifiers
const identifiers: string[] = ["fleetOne", "southEast"];
rideShareDriver.publish(payloadArrayBuffer, identifiers);
/**
* ----- RECEIVE data on Topic name -----
*/
rideShareDriver.onReceive((received: IResponse) => {
const { data, nqlIdentifiers, topicName } = received;
const stringData: string = uint8ArrayToString(data);
const receivedData = JSON.parse(stringData);
console.log(receivedData);
//{
// driverId: "6a9d03f5-bc0f-4516-9b51-c223a6cac0d2",
// driverCurrentLocation: {
// lat: "1234",
// lng: "34564",
// },
// }
console.log(nqlIdentifiers);
// ["surroundingTile:800:802"]
console.log(topicName);
// rideShareDriver
});
Getting Started
Before we can start coping and pasting example code we first have to set up the environment.
Follow the below step
- Create a Project
- Create a Tunnel
- What is NQL identifiers?
- Create a Topic
- Authentication
- Usage and Billing
Create a Project
To get started, we need to create a new project. With a NoLag project, you can manage the following:
- User access.
- API key access.
- Project Billing
- Creating new Tunnels.
Create a Tunnel
The Tunnel serves as the pathway for data transmission between devices. It also functions as a flexible environment where you can create multiple instances for different purposes, such as "Production," "Staging," or sandbox environments for developers.
Some key points to keep in mind:
- Topics assigned to one Tunnel are isolated from other Tunnels, even if they share the same name.
- Each Tunnel allows for one socket connection only.
- Device tokens are bound to a single Tunnel.
- Tunnels have their own user management system, which makes it easy to grant specific access to different Tunnels.
Sandbox Tunnels
Sandbox Tunnels function exactly the same as regular Tunnels, with the only difference being resource limitations. All sandbox Tunnels share the same resource limits.
What is NQL identifiers?
NQL(NoLag Query Language) identifiers can be thought of as sub-Topics within the NoLag Query Language. These identifiers act as query points within the NoLag message broker and consist of a list of values.
this.playerMovement.addIdentifiers([
"clanId:9482f8ee-26d0-4a92-97d3-95e99c764e59",
"surroundingTile:800:802",
"biome-4",
]);
this.playerMovement.removeIdentifiers(["surroundingTile:800:802"]);
As a Subscriber
The Subscriber can listen to the Topic and the list of identifiers attached to it. A list of identifiers represents a AND operation.
Ex. IdentifierOne AND IdentifierTwo
As a Publisher
The Publisher can send messages to the Topic and optionally specify one or more identifiers..
NQL identifiers
NQL identifiers are dynamic, meaning they can be added or removed from a Topic implemented by a device.
NQL diagram
In the diagram you can see two wind turbines each publishing one message to the Topic "turbineOutput" and each with a different set of NQL identifiers.
NoLag will then distribute the messages to the Subscribers using the NQL identifiers.
Create a Topic
Topics are the events or triggers that a Subscriber will listen to and a Publisher will send data to. Topics are attached to a Tunnel, which is grouped under a Project.
Topics are static
Topics are static and created in the NoLag portal or via API calls. They can only be changed or removed from a Tunnel via the portal or API calls. We believe that having static Topics and dynamic NQL identifiers will make it easier to build secure, scalable real-time applications.
While Topics are static, you can easily set or remove a Topic from a subscriber. Topics have several features, including:
- NoEcho This is switched on by default. A device could subscribe and publish on the same Topic name. NoEcho, as the name suggests, stops the publisher from sending data to its own subscription.
- Advance webhook - Trigger Every time messages are sent to a Topic, message data can be sent to an API endpoint.
- Advance webhook - Hydrate When a device connects to the NoLag message broker, the device could be hydrated with data from a specific endpoint.
- Status A Topic can be switched off.
Authentication
Device access Tokens are a key feature of NoLag and the cornerstone for securing device connections. All connections to a Tunnel require a Device Token, which can have several options:
- Access Permission
Determines the level of access the Device Token has, including the ability to publish and subscribe to Topics, publish only, or subscribe only. - Expire in
Specifies how long the Device Token will remain valid, in seconds. - Lock Topics
Prevents the device from subscribing or publishing to Topics that are not on the allowed list. - Allowed Topics
A list of Topics and Identifiers that are assigned to a Device Token. If the Device Token is not locked, the device can also subscribe or publish to other Topics not on the list.
Usage and Billing
Message Size
There are no publishing frequency limits but there are payload size limits.
Message transport data size can not exceed 16KB. Exceeding the allowed transport size will disconnect your device from the Tunnel.
Message transport size is made up of "topicName", "identifiers" and "payload".
Connection cost
Client will be billed for the number of seconds a device is connected to a Tunnel server.
Data transfer cost
Clients will be billed for the number of bytes egressing the Tunnel servers. This will also include data being sent between Tunnel locations.
Ex. If all your clients are in one region you will only be billing for data leaving the Tunnel server.
Ex. If you have clients all over the world and data is being sent between Tunnels servers, you will be billed for data leaving each Tunnel location and also data traveling between Tunnel locations.
Billing period
The billing period is based on a monthly cycle and starts on the first day of the month. At the end of each billing cycle, clients will receive an invoice for their usage.
Pricing model
NoLag follows a usage-based pricing model, meaning that clients are only charged for the resources they consume during the billing period. There are no upfront costs or long-term commitments.
Billing details
Clients can view their usage and billing details in the NoLag dashboard, which provides real-time visibility into their data transfer and connection costs. The dashboard also allows clients to set up alerts and notifications for cost thresholds and usage limits.
Client SDK
Connecting to a Tunnel
To connect to a NoLag Tunnel, you will need to use a supported client library or implement the NoLag API in your application. The client libraries available include TypeScript others coming soon. The libraries abstract the details of the underlying protocols and allow you to focus on building your application logic.
When connecting to a NoLag Tunnel, you don't need to specify a server location as the connection will automatically be routed to the closest server. This ensures optimal performance and reduces latency.
Once you have established a connection, you can start subscribing to Topics and publishing messages to them. You can also use NQL identifiers to filter messages that you want to receive or send. Remember to keep in mind the message size limits and connection costs to ensure optimal performance and cost-effectiveness.
// import package
import { WebSocketClient } from "nolag";
import type { ITunnel, ITopic } from "nolag";
const deviceToken: string = "<device_token_goes_here>";
// Connect to Tunnel
const nolagClient: ITunnel = await WebSocketClient(deviceToken);
// get device token ID
console.log(nolagClient.deviceTokenId);
Client instance
Import function |
---|
WebSocketClient |
Argument | Required | Type | Description |
---|---|---|---|
deviceToken | true | string | Device token generated via NoLag portal or API. |
Return
ITunnel
Client Instance
Methods
Instances
Properties
Callbacks
Client subscribe to a Topic
You can subscribe to any valid Topic name. Topic names are created in the NoLag portal or via a API call.
Subscribe to Topic
const topicOne: ITopic = nolagClient.subscribe("topicOne");
Subscribe to Topic with NQL identifiers attached
const topicTwo: ITopic = nolagClient.subscribe("topicTwo", [
"identifier_1",
"identifier_2",
"identifier_3",
]);
Method call
Instance | Method name |
---|---|
TunnelInstance | subscribe |
Argument | Required | Type | Description |
---|---|---|---|
topicName | yes | string | Name of the topic you want to subscribe to. |
identifiers | no | [...value{string}] | List of NQL identifiers attached to Topic Name |
Return
ITopic
Client publish to a Topic
Instance | Method name |
---|---|
TunnelInstance | publish |
Argument | Required | Type | Description |
---|---|---|---|
topicName | yes | string | Name of the topic you want to send a message to. |
payload | yes | ArrayBuffer | Data to send via Topic name. |
identifiers | no | [...value{string}] | List of NQL identifiers attached to Topic Name |
Publish message
import { stringToArrayBuffer } from "nolag";
// required
const topicName: string = "topicTwo";
// required
const payload: ArrayBuffer = stringToArrayBuffer("This is your first message");
// optional
const identifiers: string[] = ["identifier_4"];
nolagClient.publish(topicName, payload, identifiers);
Client unsubscribe from Topic
Method call
Instance | Method name |
---|---|
TunnelInstance | removeTopic |
Argument | Required | Type | Description |
---|---|---|---|
topicName | yes | string | The name of the topic you want to unsubscribe from. |
nolagClient.removeTopic("topicOne");
Return
boolean
Client get Topic instance
Method call
Instance | Method name |
---|---|
TunnelInstance | getTopic |
Argument | Required | Type | Description |
---|---|---|---|
topicName | yes | string | The name of the topic instance. |
const topicOne: Topic = nolagClient.getTopic("topicOne");
Return
ITopic
Client trigger disconnect
Method call
Instance | Method name |
---|---|
TunnelInstance | disconnect |
nolagClient.disconnect();
Return
ITunnel
Client receive message callback
Instance | Method name |
---|---|
TopicInstance | onReceive |
Argument | Required | Type | Description |
---|---|---|---|
callbackFn | yes | Function | Callback will fire on message received |
Callback Function
Argument | Required | Type | Description |
---|---|---|---|
received | yes | IResponse |
Receive message
import { uint8ArrayToString } from "nolag";
nolagClient.onReceive((received) => {
const { data, topicName, nqlIdentifiers } = received;
const parseData = JSON.parse(uint8ArrayToString(data));
});
On disconnect callback
Method call
Instance | Method name |
---|---|
TunnelInstance | onDisconnect |
Argument | Required | Type | Description |
---|---|---|---|
callbackFn | yes | Function | Callback will fire after connection loss |
nolagClient.onDisconnect(() => {
// lost connection
});
Return
ITunnel
On re-connect callback
Method call
Instance | Method name |
---|---|
TunnelInstance | onReconnect |
Argument | Required | Type | Description |
---|---|---|---|
callbackFn | yes | Function | Callback will fire when device reconnects |
nolagClient.onReconnect(() => {
// successful connection made
});
Return
ITunnel
On error callback
Method call
Instance | Method name |
---|---|
TunnelInstance | onError |
Argument | Required | Type | Description |
---|---|---|---|
callbackFn | yes | Function | Callback will fire on any connection errors |
Callback Function
Argument | Required | Type | Description |
---|---|---|---|
errors | yes | ConnectionErrors | Errors sent from message broker |
nolagClient.onError((errors: ConnectionErrors) => {
// received errors
console.log(errors);
});
Return
ITunnel
Properties
Device Token ID
Property | Description |
---|---|
deviceTokenId | Device Token is a unique identifier that is used to authenticate a device and grant it access to a specific Tunnel. It is attached to the token used to connect to the Message Broker, allowing the device to establish a secure and authorized connection. |
console.log(nolagClient.deviceTokenId);
Topic Instance
Methods
Callbacks
Topic add NQL identifiers
Instance | Method name |
---|---|
Topic | addIdentifiers |
Argument | Required | Type | Description |
---|---|---|---|
identifiers | true | [...value{string}] | Extra list of strings that the device will be listening. |
Add identifiers
let topicTwo: ITopic = nolagClient.subscribe("topicTwo");
// or if you already subscribed to "topicTwo" then use the below method
topicTwo: ITopic = nolagClient.getTopic("topicTwo");
topicTwo.addIdentifiers([
"identifier_1",
"identifier_2",
"identifier_3",
"identifier_4",
]);
Return
ITopic
Topic remove NQL identifiers
Instance | Method name |
---|---|
Topic | removeIdentifiers |
Argument | Required | Type | Description |
---|---|---|---|
identifiers | true | [...value{string}] | Remove identifiers from your subscription |
Remove identifiers
topicTwo.removeIdentifiers(["identifier_1", "identifier_2"]);
Return
ITopic
Topic publish
Instance | Method name |
---|---|
TopicInstance | publish |
Argument | Required | Type | Description |
---|---|---|---|
payload | true | string | Message you want to send to the Topic. |
identifiers | optional | [...value{string}] | Send messages only to these identifiers |
Publish message
import { stringToArrayBuffer } from "nolag";
// required
const payload: ArrayBuffer = stringToArrayBuffer("This is your second message");
// optional
const identifiers: string[] = ["identifier_4"];
topicTwo.publish(payload, identifiers);
Return
ITopic
Topic receive message callback
Instance | Method name |
---|---|
TopicInstance | onReceive |
Argument | Required | Type | Description |
---|---|---|---|
callbackFn | yes | Function | Callback will fire on message received |
Callback Function
Argument | Required | Type | Description |
---|---|---|---|
received | yes | IResponse |
Receive message
import { uint8ArrayToString } from "nolag";
topicTwo.onReceive((received) => {
const { data, topicName, nqlIdentifiers } = received;
const parseData = JSON.parse(uint8ArrayToString(data));
});
Topic unsubscribe
Method call
Instance | Method name |
---|---|
Topic | unsubscribe |
topicTwo.unsubscribe();
Return
boolean
API
Create API instance
Before you can make use of the API you need to generate a API token in the NoLag portal.
import { Api, IApiTunnel } from "nolag";
const apiKey = "[api_key_goes_here]";
const nolagApi: IApiTunnel = await Api(accessToken);
Methods
- Message Broker
- Topic methods
- Device methods
Topic Create
HTTP Request
POST https://api.nolag.app/v1/tunnels/:tunnelId/topics
curl "https://api.nolag.app/v1/tunnels/:tunnelId/topics" \
-X POST \
-H "X-API-Key: [api_key_goes_here]"
-H "Content-Type: application/json"
-d "[payload_goes_here]"
const payload: ITopicModel = {
name: "TestTopic",
status: "active",
type: "active",
triggerApi: "active",
hydrateApi: "active",
noEcho: false,
};
await nolagApi.tunnels("[tunnel_id_goes_here]").topic.createTopic(payload);
Method
Instance | Namespace | Method name |
---|---|---|
ApiTunnel | tunnels.topic | createTopic |
Argument | Required | Type | Description |
---|---|---|---|
topicModel | yes | ITopicModel |
response
Topic Get Record
HTTP Request
GET https://api.nolag.app/v1/tunnels/:tunnelId/topics/:topicId
curl "https://api.nolag.app/v1/tunnels/:tunnelId/topics/:topicId" \
-X GET \
-H "X-API-Key: [api_key_goes_here]"
-H "Content-Type: application/json"
await nolagApi
.tunnels("[tunnel_id_goes_here]")
.topic.getTopic("[topic_id_goes_here]");
Method
Instance | Namespace | Method name |
---|---|---|
ApiTunnel | tunnels.topic | getTopic |
Argument | Required | Type | Description |
---|---|---|---|
TopicId | yes | string |
response
Topic Update
HTTP Request
PATCH https://api.nolag.app/v1/tunnels/:tunnelId/topics/:topicId
curl "https://api.nolag.app/v1/tunnels/:tunnelId/topics/:topicId" \
-X PATCH \
-H "X-API-Key: [api_key_goes_here]"
-H "Content-Type: application/json"
-d "[payload_goes_here]"
const payload: ITopicModel = {
name: "TestTopic",
status: "active",
type: "active",
triggerApi: "active",
hydrateApi: "active",
noEcho: false,
};
await nolagApi
.tunnels("[tunnel_id_goes_here]")
.topic.updateTopic("[topic_id_goes_here]", payload);
Method
Instance | Namespace | Method name |
---|---|---|
ApiTunnel | tunnels.topic | updateTopic |
Argument | Required | Type | Description |
---|---|---|---|
topicModel | yes | ITopicModel |
response
Topic Delete
HTTP Request
DELETE https://api.nolag.app/v1/tunnels/:tunnelId/topics/:topicId
curl "https://api.nolag.app/v1/tunnels/:tunnelId/topics/:topicId" \
-X DELETE \
-H "X-API-Key: [api_key_goes_here]"
-H "Content-Type: application/json"
await nolagApi
.tunnels("[tunnel_id_goes_here]")
.topic.deleteTopic("[topic_id_goes_here]");
Method
Instance | Namespace | Method name |
---|---|---|
ApiTunnel | tunnels.topic | deleteTopic |
Argument | Required | Type | Description |
---|---|---|---|
topicModel | yes | ITopicModel |
response
Topic List
HTTP Request
GET https://api.nolag.app/v1/tunnels/:tunnelId/topics?[query_params_go_here]
curl "https://api.nolag.app/v1/tunnels/:tunnelId/topics?[query_params_go_here]" \
-X GET \
-H "X-API-Key: [api_key_goes_here]"
-H "Content-Type: application/json"
await nolagApi
.tunnels("[tunnel_id_goes_here]")
.topic.listTopics("[topic_id_goes_here]");
Method
Instance | Namespace | Method name |
---|---|---|
ApiTunnel | tunnels.topic | listTopics |
Argument | Required | Type | Description |
---|---|---|---|
topicQuery | yes | ITopicQuery |
Response
Argument | Type |
---|---|
records | [...ITopicModel] |
pagination | IPagination |
Device Create
HTTP Request
POST https://api.nolag.app/v1/tunnels/:tunnelId/devices
curl "https://api.nolag.app/v1/tunnels/:tunnelId/devices" \
-X POST \
-H "X-API-Key: [api_key_goes_here]"
-H "Content-Type: application/json"
-d "[payload_goes_here]"
const payload: IDeviceTokenModel = {
name: "TestDevice",
accessPermission: "pubSub",
staticTopics: null,
lockTopics: false,
expireIn: 1000,
};
await nolagApi.tunnels("[tunnel_id_goes_here]").devices.createDevice(payload);
Method
Instance | Namespace | Method name |
---|---|---|
ApiTunnel | tunnels.devices | createDevice |
Argument | Required | Type | Description |
---|---|---|---|
deviceTokenModel | yes | IDeviceTokenModel |
response
Device Get Record
HTTP Request
GET https://api.nolag.app/v1/tunnels/:tunnelId/devices/:deviceTokenId
curl "https://api.nolag.app/v1/tunnels/:tunnelId/devices/:deviceTokenId" \
-X GET \
-H "X-API-Key: [api_key_goes_here]"
-H "Content-Type: application/json"
await nolagApi
.tunnels("[tunnel_id_goes_here]")
.devices.getDevice("[device_id_goes_here]");
Method
Instance | Namespace | Method name |
---|---|---|
ApiTunnel | tunnels.devices | getDevice |
Argument | Required | Type | Description |
---|---|---|---|
deviceTokenId | yes | string |
response
Device Update
HTTP Request
PATCH https://api.nolag.app/v1/tunnels/:tunnelId/devices/:deviceTokenId
curl "https://api.nolag.app/v1/tunnels/:tunnelId/devices/:deviceTokenId" \
-X PATCH \
-H "X-API-Key: [api_key_goes_here]"
-H "Content-Type: application/json"
-d "[payload_goes_here]"
const payload: IDeviceTokenModel = {
name: "TestDevice",
accessPermission: "pubSub",
staticTopics: null,
lockTopics: false,
expireIn: 1000,
};
await nolagApi
.tunnels("[tunnel_id_goes_here]")
.devices.updateDevice("[device_id_goes_here]", payload);
Method
Instance | Namespace | Method name |
---|---|---|
ApiTunnel | tunnels.devices | updateDevice |
Argument | Required | Type | Description |
---|---|---|---|
deviceTokenModel | yes | IDeviceTokenModel |
response
Device Delete
HTTP Request
DELETE https://api.nolag.app/v1/tunnels/:tunnelId/devices/:deviceTokenId
curl "https://api.nolag.app/v1/tunnels/:tunnelId/devices/:deviceTokenId" \
-X DELETE \
-H "X-API-Key: [api_key_goes_here]"
-H "Content-Type: application/json"
await nolagApi
.tunnels("[tunnel_id_goes_here]")
.devices.deleteDevice("[device_id_goes_here]");
Method
Instance | Namespace | Method name |
---|---|---|
ApiTunnel | tunnels.devices | deleteDevice |
Argument | Required | Type | Description |
---|---|---|---|
deviceTokenModel | yes | IDeviceTokenModel |
response
Device List
HTTP Request
GET https://api.nolag.app/v1/tunnels/:tunnelId/devices?[query_params_go_here]
curl "https://api.nolag.app/v1/tunnels/:tunnelId/devices?[query_params_go_here]" \
-X GET \
-H "X-API-Key: [api_key_goes_here]"
-H "Content-Type: application/json"
await nolagApi
.tunnels("[tunnel_id_goes_here]")
.devices.listDevices("[device_id_goes_here]");
Method
Instance | Namespace | Method name |
---|---|---|
ApiTunnel | tunnels.devices | listDevices |
Argument | Required | Type | Description |
---|---|---|---|
deviceListQuery | yes | IDeviceListQuery |
Response
Argument | Type |
---|---|
records | [...IDeviceTokenModel] |
pagination | IPagination |
Publish messages
HTTP Request
POST https://tunnel.nolag.app/tunnels/:tunnelId/publish
curl "https://tunnel.nolag.app/tunnels/:tunnelId/publish" \
-X POST \
-H "X-API-Key: [api_key_goes_here]"
-H "Content-Type: text/plain"
-d "[payload_goes_here]"
import { stringToArrayBuffer, IHttpPublish } from "nolag";
const payload: IHttpPublish = {
data: stringToArrayBuffer(
JSON.stringify({
bulbStatus: true,
})
),
tunnelName: "topicTwo",
identifiers: ["identifier_1", "identifier_4"],
};
await nolag.publish(payload);
Method
Instance | Namespace | Method name |
---|---|---|
ApiTunnel | tunnels | publish |
Argument | Required | Type | Description |
---|---|---|---|
httpPublish | true | IHttpPublish |
Response
boolean
Transport Protocol
If your project doesn't have SDK support yet, this guide will help you get set up.
Servers
- Websocket Tunnel URL
wss://tunnel.nolag.app/ws
Connecting and Authentication sequence
The following steps explain the connection and authentication of a connecting device
- Device connects to Message Broker server
- Message Broker sends an ACK
- Device sends
deviceAccessToken
to the Message Broker - Message Broker sends back two ACKACK and the deviceTokenId
- Device starts sending Transports
Example sequence:
ACK
[deviceAccessToken]
ACKACK[deviceTokenId]
[transport_payload_here]
Transport Payload
A transport payload consists of the following:
[TopicName US EAction RS Identifier1 VT Identifier2 US EAction GS DeviceData]
Transport sections
Group Separator GS
Splits the Topic Name and NQL identifiers from the Device dataRecord Separator RS
Splits the Topic Name from the NQL identifiersUnit Separator US
Reveals the "actions" that we need to perform on the Topic Name and NQL identifier records. These actions might be a "add" or a "delete"
The message broker uses UTF-8 character encoding to receive and interpret an array of bytes as a sequence of characters.
Example:
Payload: testOne[RS]Identifier1[VT]Identifier2[US]a[GS]device-data-here
Hex:
74 65 73 74 4F 6E 65 1E 49 64 65 6E 74 69 66 69 65 72 31 0B 49 64 65 6E 74 69 66 69 65 72 32 1F 61 1D 64 65 76 69 63 65 2D 64 61 74 61 2D 68 65 72 65
Acknowledge
As soon as the device connects to the Message Broker will send an Acknowledgement of the connection
DEC | HEX | BIN | Symbol |
---|---|---|---|
6 | 06 | 00000110 | ACK |
Group Separator
Split Topic and NQL identifiers from device data
DEC | HEX | BIN | Symbol |
---|---|---|---|
29 | 1D | 00011101 | GS |
Record Separator
Split Topic from NQL identifiers
DEC | HEX | BIN | Symbol |
---|---|---|---|
30 | 1E | 00011110 | RS |
Unit Separator
Split the record with the command to send
DEC | HEX | BIN | Symbol |
---|---|---|---|
31 | 1F | 00011111 | US |
Vertical bar
VT acts as an OR operator
DEC | HEX | BIN | Symbol |
---|---|---|---|
11 | 0B | 00001011 | VT |
Types
Enums
EAccessPermission
Used to specify which type of Pub/Sub access the associated Device Token has.
Device permissions
Key | Value | Description |
---|---|---|
Subscribe | "subscribe" | Can only Subscribe |
Publish | "publish" | Can only Publish |
PubSub | "pubSub" | Can Publish and Subscribe |
EStatus
Set the status of a Topic. Active, the Topic can be used. Inactive, Topic can not be used.
Key | Value | Description |
---|---|---|
Active | "active" | |
Inactive | "inactive" |
EAction
Used as a command to indicate to the Message Broker that a device wants to add or delete a subscription to a topic, or to add and delete identifiers set on a topic.
Key | Value | Description |
---|---|---|
Add | "a" | When adding anything to the transport |
Delete | "d" | When removing anything to the transport |
Interfaces
IPaginated
Paginated result received from the API end-point.
Property | Type | Description |
---|---|---|
records | [...DTO] | List of records |
pagination | IPagination |
IPagination
Pagination details indicating the current status of your pagination query.
Key | Type | Description |
---|---|---|
page | integer | Current page |
size | integer | Records per page |
hasPrevious | boolean | From the current page, are there any previous records |
hasNext | boolean | From the current page, are there any next records |
total | integer | Total number of records |
IDeviceListQuery
Available query parameters to query a device list.
Key | Type | Description |
---|---|---|
deviceAccessToken | string | This token is your access token key |
expireFromDate | integer | Find expire dates after this date |
expireToDate | integer | Find expire dates before this date |
name | string | Name of the Device |
search | string | search for names |
size | integer | Number of records on the page |
page | integer | Page number |
IDeviceTokenModel
Properties in creating or updating a Device Token.
Key | Type | Description |
---|---|---|
name | string | This token is your access token key |
accessPermission | EAccessPermission | |
deviceTokenId | string | Record ID |
deviceAccessToken | string | This token is your access token key |
tunnelId | string | Tunnel ID this device is attached to |
staticTopics | IStaticTopic | |
lockTopics | boolean | Page number |
expireIn | integer | Expire in seconds from when the device token was created |
expireDate | integer | Calculated date of when this will happen |
IStaticTopic
Static Topics, are a group of Topic names and Identifiers. These are attached to a Device Token. In the scenario where the Device Token is locked, the Device only has access to its Static Topics.
Key | Type | Description |
---|---|---|
name | string | Topic name that static on the Device Token |
identifiers | [...value{string}] | Static identifiers |
IHttpPublish
Sending messages to the Message Broker via HTTP call
Key | Type | Description |
---|---|---|
data | ArrayBuffer | Data received from Topic subscription |
tunnelName | string | Topic name |
identifiers | string | List of NQL identifiers |
IResponse
Response received from Message Broker
Key | Type | Description |
---|---|---|
data | Uint8Array | Data received from Topic publish |
topicName | string | Topic name |
nqlIdentifiers | [...value{string}] | Identifiers used for this received message |
ITopicModel
Topic properties used to creating or updating a model
Key | Type | Description |
---|---|---|
topicId | ArrayBuffer | Data received from Topic subscription |
projectId | string | Topic name |
tunnelId | string | |
status | EStatus | Status of Topic |
name | string | Name of Topic |
triggerApi | ITopicApiModel | |
hydrateApi | ITopicApiModel | |
noEcho | boolean | Do not publish to Topic if device is also subscribed to the Topic |
ITopicApiModel
Advance websocket setup properties
Key | Type | Description |
---|---|---|
url | string | Data received from Topic subscription |
queryParams | object | URL query parameters |
headers | object | URL header parameters |
ITopicQuery
Query parameters available for a Topic
Key | Type | Description |
---|---|---|
topicId | string | |
projectId | string | |
tunnelId | string | |
status | EStatus | Status of Topics |
name | string | Topic name |
size | integer | Size of records returned |
page | integer | Current page number |
search | string | Search Topic name |
ITriggerRequest
List of field related error, it can also contain a nested list of error
Key | Type | Description |
---|---|---|
topicName | string | Topic name that triggered this Hydration |
identifiers | [...{string}] | List of identifiers attached to the Topic for tis Device |
data | string | Data triggered by this Topic trigger |
deviceId | string | UUID for the device making this request |
IHydrateRequest
Data sent to server on a Hydration request
Key | Type | Description |
---|---|---|
topicName | string | Topic name that triggered this Hydration |
identifiers | [...{string}] | List of identifiers attached to the Topic for tis Device |
deviceId | string | UUID for the device making this request |
IErrorMessage
Error model received from Message Broker or API
Key | Type | Description |
---|---|---|
id | string | ID for this error, can use this to find the issue |
code | integer | HTTP code associated with this error |
msg | string | Error message, explaining the HTTP status code received |
description | string | Additional information attached to the error |
errors | [...IErrorsModel] | If the error relates to field, errors, this ist will give more information on the error |
IErrorsModel
List of field related error, it can also contain a nested list of error
Key | Type | Description |
---|---|---|
property | string | Property that had the error |
value | string | Properties current value |
descriptions | string | What the error was on the property |
errors | [...IErrorsModel] or undefined |
Errors
Message Broker Errors
Error Code | Message | Description |
---|---|---|
401 | "Not authorized to use service." | User validation failed. |
404 | "Can not find resource" | Server can not find what you were looking for. |
disconnect | "Payload Too Large" | Payload sent to message broker exceeds Message Size. |
API Errors
The NoLag API uses the following error codes:
Error Code | Message | Description |
---|---|---|
400 | "Invalid request" | System does not understand request. |
401 | "Not authorized to use service." | User validation failed. |
403 | "Not allowed to access resource." | Not allowed to access resource. |
404 | "Can not find resource" | Server can not find what you were looking for. |
409 | "Duplicate resource found" | Resource already in system. |
500 | "System error" | Something within the system has hit a error. |