MQTT, STOMP and WebSockets
Messaging, stream subscriptions and alternative transports.
These examples document the original platform. Use your own deployment; this website does not provide the former hosted API or account service.
Introduction
servIoTicy allows for the interaction with the platform through protocols that are not HTTP/REST. Support for MQTT, STOMP-over-TCP and STOMP-over-WS is provided. This page describes how to leverage this protocols for easy interaction with the platform.
They can be used in three different forms:
- For cient/server interaction with servIoTicy, emulating the behaviour of the REST API
- For data streams subscriptions: A client can subscribe to a data stream and receive all the updates being send to a SO stream. Note that given that the platform provides eventual consistency, this is a good way to get most recent updates for a SO stram asynchronously and in real-time. Polling is not recommended.
- For actuations: This is described in a separate document here. Some information contained in this page is still relevant.
Information for communicating with the platform using MQTT/WS/TCP:
- MQTT Endpoint: api.servioticy.com:1883
- STOMP/TCP Endpoint: api.servioticy.com:1883
- STOMP/WS Endpoint: api.servioticy.com:61623
- User: compose
- Password: shines
Topics:
- Sending data from the Web Object: “<API_TOKEN>/from” (MQTT) – “/topic/<API_TOKEN>.from” (STOMP)
- Sending data to the Web Object (HTTP responses): “<API_TOKEN>/to” (MQTT) – “/topic/<API_TOKEN>.to” (STOMP)
- Updates produced by subscriptions: “<API_TOKEN>/<SO_Id>/streams/<streamId>/updates” (MQTT) – “/topic/<API_TOKEN>.<SO_Id>.streams.<streamId>.updates” (STOMP)
Important: Notice that the topics used in MQTT and STOM follow a different format. More information found here (MQTT) and here (STOMP)
Subscribing to data streams:
We would POST the following JSON document to the URL:
http://api.servioticy.com/SOid/streams/streamID/subscriptions
Note that the filed “destination” is here the API_TOKEN of the subscriber.
Example topic:
“M2JhMmRkMDEtZTAwZi00ODM5LThmYTktOGU4NjNjYmJmMjc5N2UzNzYwNWItNTc2ZS00MGVlLTgyNTMtNTgzMmJhZjA0ZmIy/1396461657731411aa73c28444ecf9a8c803e62312fd1/streams/location/updates”
{
"callback": "pubsub",
"destination": "M2JhMmRkMDEtZTAwZi00ODM5LThmYTktOGU4NjNjYmJmMjc5N2UzNzYwNWItNTc2ZS00MGVlLTgyNTMtNTgzMmJhZjA0ZmIy",
}Client-Server interaction:
REST API is mapped on top of a topic using the following structure (note the use of an optional “messageId” field to match queries and responses):
{
"meta": {
"authorization": "API_TOKEN HERE",
"method": "PUT/GET/POST",
"url": "/full/path/to/destination"
"messageId": "random string to match requests and responses"
},
"body": {
<STRUCTURE OF THE JSON DOCUMENT YOU SHOULD SEND TO THE REST API>
}
}An example of how to to list all the SOs belonging to a user:
{
"meta": {
"authorization": "API_TOKEN HERE",
"method": "GET",
"url": "/",
"messageId": 123456
}
}
An example of how to push data to the platform:
{
"meta": {
"authorization": "API_TOKEN HERE",
"method": "PUT",
"url": "/13944639303973f5530eab507412d88bef305089a7720/streams/weather",
"messageId": 123456
},
"body": {
"lastUpdate": 1199192932,
"channels": {
"location": {
"current-value": "40.12,-71.34",
"unit": "degrees"
},
"temperature": {
"current-value": 33,
"unit": "degrees"
}
}
}
}
Code samples
A sample python code for pushing data to the platform (based on Paho):
import paho.mqtt.publish as publish
import paho.mqtt.client as mqtt
putData = """
{
"meta": {
"authorization": "API_TOKEN HERE",
"method": "PUT",
"url": "/13944639303973f5530eab507412d88bef305089a7720/streams/weather"
},
"body": {
"lastUpdate": 1199192932,
"channels": {
"location": {
"current-value": "40.12,-71.34",
"unit": "degrees"
},
"temperature": {
"current-value": 33,
"unit": "degrees"
}
}
}
}
"""
getAllSO = """
{
"meta": {
"authorization": "API_TOKEN HERE",
"method": "GET",
"url": "/"
}
}
"""
def on_connect(mqttc, obj, rc):
mqttc.publish("API_TOKEN HERE/from", getAllSO)
mqttc.publish("API_TOKEN HERE/from", putData)
def on_message(mqttc, obj, msg):
print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))
def on_log(mqttc, obj, level, string):
print(string)
mqttc = mqtt.Client()
mqttc.on_connect = on_connect
# Uncomment to enable debug messages
#mqttc.on_log = on_log
mqttc.username_pw_set("compose","shines")
mqttc.connect("api.servioticy.com", 1883, 60)
mqttc.loop_forever()
The actual Node.js multi-protocol bridge between the broker and the platform:
Note that it uses STOMP+TCP, and therefore uses a topic notation that is: “/topic/field1.field2.field3….”
var Stomp = require('stompjs');
var api = require('restler');
// Use raw TCP sockets
var client = Stomp.overTCP('api.servioticy.com', 1883);
// uncomment to print out the STOMP frames
//client.debug = console.log;
client.connect('compose', 'shines', function(frame) {
client.subscribe('/topic/*.from', function(message) {
var request = JSON.parse(message.body);
console.log("Going for a "+request.meta.method)
console.log("Posted data "+JSON.stringify(request.body))
api.json("http://api.servioticy.com"+request.meta.url,
request.body,
{headers: {'Content-Type': 'application/json', 'Authorization':request.meta.authorization}},
request.meta.method
).on('complete', function(data, response) {
data.messageId = request.meta.messageUd || null;
client.send('/topic/'+request.meta.authorization+".to",{},JSON.stringify(data))
console.log("result: "+JSON.stringify(data))
});
});
});
