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..."}
}