WebSocket API

Overview

This document describes the general Websocket publish / subscribe concept for connecting Location Cores and client services and to exchange messages and events over a websocket connection.

General omlox™ Publish / Subscribe Concept

Applications can subscribe and unsubscribe themselves to named topics. Data published to a topic will be received by all subscribers of that topic. All data sent to and received from the WebSocket connection is wrapped into the payload property of the wrapper object detailed in the next section. The following named topics are available:

location_updates

This topic is useful to retrieve real-time location updates, as well as sending location updates to the hub. Location data received by the hub is processed and then forwarded to all subscribers of this topic.

When receiving data for this topic the payload of the wrapper object contains omlox™ Location objects.

location_updates:geojson

This topic is similar to location_updates, but instead of an omlox™ Location object GeoJson feature collections are returned as payload.

When receiving data for this topic the payload of the wrapper object contains GeoJson feature collections.

collision_events

This topic is used to retrieve real-time collision events. The hub checks trackable movements for collisions and sends collision events when trackables: start to collide, continue to collide and end a collision.

When receiving data for this topic the payload of the wrapper object contains omlox™ CollisionEvent objects.

fence_events

This topic is used to inform subscribers about geofence entry and exit events. The hub implementation checks location providers and trackables for fence events and sends appropriate events to subscribers of this topic immediately for each fence entry and fence exit event.

When receiving data for this topic the payload of the wrapper object contains omlox™ FenceEvent objects.

fence_events:geojson

This topic is similar to fence_events, but instead of an omlox™ FenceEvent object GeoJson feature collections are returned as payload.

When receiving data for this topic the payload of the wrapper object contains GeoJson feature collections.

trackable_motions

This topic informs subscribers about movements of an omlox™ Trackable. For example, when one of the assigned omlox™ Location Providers changes its position.

When receiving data for this topic, the payload of the wrapper object contains omlox™ TrackableMotion objects.

To subscribe to a topic, the application sends a json encoded message. The server generates a response, either acknowledging a successful subscription / unsubscription or returns an error message.

The server also generates a subscription_id for a successful subscription. This allows an application to subscribe itself to the same topic multiple times with differing parameters and control each subscription separately. Subscriptions are otherwise automatically terminated when the websocket connection is closed.

Websocket Data Objects

Data between client and server are exchanged using a wrapper object with the following structure:

name

type

description

event

string

Any of message, subscribe, subscribed, unsubscribe, unsubscribed

topic

string

Topic name

subscription_id

int

The concrete topic subscription which generated the data

payload

array

An array containing valid omlox™ data objects (or empty)

params

object

An optional object containing key-value pairs of parameters. Parameters usually match their REST API counterparts

The field event is always required for all data exchanged between client and server. Other fields are required depending on the event type. Concrete event based data structures are detailed in the respective sections below.

Example data object containing an omlox™ location object as payload:

{
  "event": "message",
  "topic": "location_updates",
  "subscription_id": 123,
  "payload": [
    {
        "position": {
          "type": "Point",
          "coordinates": [
            5,
            4
          ]
        },
        "source": "fdb6df62-bce8-6c23-e342-80bd5c938774",
        "provider_type": "uwb",
        "provider_id": "77:4f:34:69:27:40",
        "timestamp_generated": "2019-09-02T22:02:24.355Z",
        "timestamp_sent": "2019-09-02T22:02:24.355Z"
    }
  ]
}

In case of an error the server sends a json object with event type error and the following data structure:

name

type

description

event

string

Will be error for an error object

description

string

A human readable error message

code

int

Error code

Example error object:

{
    "event": "error",
    "description": "Invalid data. The location data contains an invalid Position.",
    "code": 10005
}

The error code can be used by applications to discern the type of the error, e.g. for error handling and messaging on application side.

Possible error codes:

  • 10000: Event type is unknown

  • 10001: Unknown topic name

  • 10002: Subscription failed

  • 10003: Unsubscribe failed

  • 10004: Not authorized

  • 10005: Invalid payload data

Subscribing to a topic

Subscribing to a topic opens a connection to the websocket endpoint at e.g. ws://localhost:8081/v1/ws/socket. After successfully connecting, the client sends a subscribe request message to the server.

The subscribe request has the following structure:

name

type

description

event

string

subscribe

topic

string

Name of the topic, e.g. location_updates or fence_events

params

object

An optional object containing key-value pairs of parameters. Parameters usually match their REST API counterparts

An example subscribe request to the location_updates topic:

{
    "event": "subscribe",
    "topic": "location_updates",
    "params": {
        "crs": "EPSG:4326"
    }
}

Example subscribe request to fence events:

{
    "event": "subscribe",
    "topic": "fence_events"
}

Successful subscription response

The server responds to the subscribe request either with success response or an error response. On successful subscription the server responds with a subscribed event, a copy of the subscribed topic as well as the subscription_id for the concrete subscription.

It’s important to keep the provided subscription_id on the client side in case the client wants to maintain multiple subscriptions to the same topic with different parameters. A client may however simply close it’s connection, and all it’s subscriptions will be cleaned up on the server side.

The subscription response has the following structure:

name

type

description

event

string

On success subscribed

topic

string

Name of the topic

subscription_id

int

Topic subscription id

Example server response for a successful subscription request:

{
    "event": "subscribed",
    "topic": "location_updates",
    "subscription_id": 123
}

Unsubscribing

To unsubscribe, a client must either close the connection, or send an unsubscribe request with a concrete subscription id to the server.

The unsubscribe request has the following structure:

name

type

description

event

string

Must be unsubscribe

subscription_id

int

Topic subscription id to unsubscribe from

Example unsubscribe object:

{
    "event": "unsubscribe",
    "subscription_id": 123
}

Unsubscribe response

With a successful unsubscription, the server responds with an unsubscribed event.

Unsubscribe event structure:

name

type

description

event

string

Must be unsubscribed

topic

string

Name of the topic

subscription_id

int

Topic subscription id from which the application was successfully unsubscribed

Example unsubscribe server response:

{
    "event": "unsubscribed",
    "topic": "location_updates",
    "subscription_id": 123
}

Data submission without subscription

A client can send / publish data to the server directly over the websocket connection without a subscription. For example, a client can send raw location data to the location_updates topic; the server processes the data in the same way as the /providers/locations API and then publishes the processed location data to subscribers of the location_updates topic. A data object sent by the client must have the event type message and use one of the available writeable topics.

The message data has the following structure:

name

type

description

event

string

Must be message

topic

string

Topic name (location_updates or fence_events)

payload

array

An array containing valid omlox™ data objects (or empty)

Example message object containing raw location data for the location_updates topic:

{
  "event": "message",
  "topic": "location_updates",
  "payload": [
    {
        "position": {
          "type": "Point",
          "coordinates": [
            5,
            4
          ]
        },
        "source": "fdb6df62-bce8-6c23-e342-80bd5c938774",
        "provider_type": "uwb",
        "provider_id": "77:4f:34:69:27:40",
        "timestamp_generated": "2019-09-02T22:02:24.355Z",
        "timestamp_sent": "2019-09-02T22:02:24.355Z"
    }
  ]
}

Authorization

When authorization is enabled, each event must contain a JWT token in the params section, for example:

{
    "event": "subscribe",
    "topic": "fence_events",
    "params": {"token":"eyJhbG..."}
}

Filtering & Subscription Parametrization

The publish / subscribe API allows to filter and transform data feeds by setting parameters as key / value pairs to the params section of a subscription request. The following example shows a subscription request to trackable motions with location data projected to UTM 32 (EPSG:32632) and filtering for a certain trackable id:

{
    "event": "subscribe",
    "topic": "trackable_motions",
    "params": {
        "crs": "EPSG:32632",
        "id": "0b680db2-b39b-45be-be77-40d7d2296cb4"
    }
}

Note: There can be any number of active subscriptions made by the same client to a topic. For example, it’s possible to make two distinct subscriptions to the location_updates topic, where each subscription may filter for example for a different location provider. Subscribing to the same topic with the same parameters twice will however result in a subscription error, as is to be expected.

The following parameters are available for the respective WebSocket topics.

Parameters for topic location_updates

param

description

provider_id

Filter events matching the given provider ID

source

Filter events by source (e.g., zone)

provider_type

Filter by omlox provider type (e.g., uwb, wifi, rfid)

associated

Filter events which are currently associated to an infrastructure (e.g., relevant for wifi systems)

accuracy

Filter data where accuracy is better than or equal to the value provided

floor

Filter data matching the given floor level

crs

Project location data to the given crs. Any crs supported by omlox can be set (e.g., local, EPSG:32632)

Parameters for topic trackable_motions

param

description

id

Filter events matching the given trackable ID

provider_id

Filter events matching the provider ID

name

Filter events matching the trackable name

floor

Filter events matching given floor level

crs

Project location data to the given crs. Any crs supported by omlox can be set (e.g., local, EPSG:32632)

Parameters for topic fence_events

param

description

fence_id

Filter events matching the given fence ID

foreign_id

Filter events matching the given foreign ID

provider_id

Filter events matching the provider ID which caused the fence event

trackable_id

Filter events matching the trackable ID which was involved in the fence event

event_type

Filter for fence entry (region_entry) or fence exit (region_exit) events

Parameters for topic collision_updates

param

description

collision_id_1

Filter events where one item of the collision pair matches given id (e.g., trackable ID involved in the collision)

collision_id_2

Same as collision_id_1. Note: When both collision_id_1 and collision_id_2 are set events will effectively be filtered for collisions between these two trackables

collision_type

Filter events by collision type. One of collision_start, colliding, collision_end