blob: ed24c45a11885d3123d325fb72efa3ff0db8316b [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="keywords" content="protocol, protocol, specification, messages, thing">
<title> Things - Messages protocol specification • Eclipse Ditto • a digital twin framework</title>
<link rel="stylesheet" href="css/syntax.css">
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="css/modern-business.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="css/customstyles.css">
<link rel="stylesheet" href="css/boxshadowproperties.css">
<link rel="stylesheet" href="css/theme-ditto.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/anchor-js/2.0.0/anchor.min.js" crossorigin="anonymous"></script>
<script src="js/toc.js"></script>
<script src="js/customscripts.js"></script>
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "Organization",
"url": "https://eclipse.org/ditto/",
"logo": "https://eclipse.org/ditto/images/ditto.svg"
}
</script>
<link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="images/favicon-96x96.png" sizes="96x96">
<link rel="alternate" type="application/rss+xml" title="Eclipse Ditto Blog" href="https://www.eclipse.org/ditto/feed.xml">
<!-- Eclipse Foundation cookie consent: -->
<link rel="stylesheet" type="text/css" href="//www.eclipse.org/eclipse.org-common/themes/solstice/public/stylesheets/vendor/cookieconsent/cookieconsent.min.css" />
<script src="//www.eclipse.org/eclipse.org-common/themes/solstice/public/javascript/vendor/cookieconsent/default.min.js"></script>
<script>
$(document).ready(function() {
$("#tg-sb-link").click(function() {
$("#tg-sb-sidebar").toggle();
$("#tg-sb-content").toggleClass('col-md-9');
$("#tg-sb-content").toggleClass('col-md-12');
$("#tg-sb-icon").toggleClass('fa-toggle-on');
$("#tg-sb-icon").toggleClass('fa-toggle-off');
});
});
</script>
</head>
<script>
(function(w,d,s,l,i){
w[l]=w[l]||[];
w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});
var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),
dl=l!='dataLayer'?'&l='+l:'';
j.async=true;
j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;
f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-5WLCZXC');
</script>
<body>
<!-- Navigation -->
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container topnavlinks">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-ditto-home" href="index.html">&nbsp;<img src="images/ditto_allwhite_symbolonly.svg" class="ditto-navbar-symbol" alt="Home"> <img src="images/ditto_allwhite_textonly.svg" class="ditto-navbar-symbol-text" alt="Ditto"></a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<!-- toggle sidebar button -->
<!--<li><a id="tg-sb-link" href="#"><i id="tg-sb-icon" class="fa fa-toggle-on"></i> Nav</a></li>-->
<!-- entries without drop-downs appear here -->
<li><a href="blog.html">Blog</a></li>
<li><a href="intro-overview.html">Documentation</a></li>
<li><a href="http-api-doc.html">HTTP API</a></li>
<li><a href="sandbox.html">Sandbox</a></li>
<li><a href="https://github.com/eclipse/ditto" target="_blank">GitHub</a></li>
<li><a href="https://github.com/eclipse/ditto-examples" target="_blank">GitHub examples</a></li>
<!-- entries with drop-downs appear here -->
<!-- conditional logic to control which topnav appears for the audience defined in the configuration file.-->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Links<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="https://projects.eclipse.org/projects/iot.ditto" target="_blank">Eclipse Ditto Project</a></li>
<li><a href="https://www.eclipse.org/forums/index.php/f/364/" target="_blank">Forum</a></li>
<li><a href="https://ci.eclipse.org/ditto/" target="_blank">Jenkins</a></li>
<li><a href="https://dev.eclipse.org/mhonarc/lists/ditto-dev/" target="_blank">Mailing list archives</a></li>
<li><a href="https://gitter.im/eclipse/ditto" target="_blank">Gitter.im chat</a></li>
</ul>
</li>
<!--comment out this block if you want to hide search-->
<li>
<!--start search-->
<div id="search-demo-container">
<input type="text" id="search-input" placeholder="search...">
<ul id="results-container"></ul>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/simple-jekyll-search/0.0.9/jekyll-search.js" type="text/javascript"></script>
<script type="text/javascript">
SimpleJekyllSearch.init({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
dataSource: 'search.json',
searchResultTemplate: '<li><a href="{url}" title="Things - Messages protocol specification">{title}</a></li>',
noResultsText: 'No results found.',
limit: 10,
fuzzy: true,
})
</script>
<!--end search-->
</li>
</ul>
</div>
</div>
<!-- /.container -->
</nav>
<!-- Page Content -->
<div class="container">
<div id="main">
<!-- Content Row -->
<div class="row">
<!-- Sidebar Column -->
<div class="col-md-3" id="tg-sb-sidebar">
<ul id="mysidebar" class="nav">
<li class="sidebarTitle">
<label for="docVersion">Eclipse Ditto version:</label>
<div class="select-wrapper">
<select id="docVersion" name="docVersion">
<option value="">development</option>
<option value="1.0">1.0</option>
<option value="1.1">1.1</option>
<option value="1.2">1.2</option>
<option value="1.3">1.3</option>
<option value="1.4">1.4</option>
<option value="1.5">1.5</option>
</select>
</div>
<div id="dev-warning">
<div markdown="span" class="alert alert-warning" role="alert" style="font-size:0.6em"><i class="fa fa-warning"></i> <b>Important:</b> This documentation reflects the latest 'development'. You might want to choose a released version.</div>
</div>
</li>
<li class="subfolders">
<a href="#"><span></span>Introduction</a>
<ul>
<li><a href="intro-overview.html">Overview</a></li>
<li><a href="intro-digitaltwins.html">Digital twins</a></li>
<li><a href="intro-hello-world.html">Hello world</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Release Notes</a>
<ul>
<li><a href="release_notes_151.html">1.5.1</a></li>
<li><a href="release_notes_150.html">1.5.0</a></li>
<li><a href="release_notes_140.html">1.4.0</a></li>
<li><a href="release_notes_130.html">1.3.0</a></li>
<li><a href="release_notes_121.html">1.2.1</a></li>
<li><a href="release_notes_120.html">1.2.0</a></li>
<li><a href="release_notes_115.html">1.1.5</a></li>
<li><a href="release_notes_113.html">1.1.3</a></li>
<li><a href="release_notes_112.html">1.1.2</a></li>
<li><a href="release_notes_111.html">1.1.1</a></li>
<li><a href="release_notes_110.html">1.1.0</a></li>
<li><a href="release_notes_100.html">1.0.0</a></li>
<li><a href="release_notes_090.html">0.9.0</a></li>
<li><a href="release_notes_080.html">0.8.0</a></li>
<li class="subfolders">
<a href="#"><span></span>Milestone releases</a>
<ul>
<li><a href="release_notes_100-M2.html">1.0.0-M2</a></li>
<li><a href="release_notes_100-M1a.html">1.0.0-M1a</a></li>
<li><a href="release_notes_090-M2.html">0.9.0-M2</a></li>
<li><a href="release_notes_090-M1.html">0.9.0-M1</a></li>
<li><a href="release_notes_080-M3.html">0.8.0-M3</a></li>
<li><a href="release_notes_080-M2.html">0.8.0-M2</a></li>
<li><a href="release_notes_080-M1.html">0.8.0-M1</a></li>
<li><a href="release_notes_030-M2.html">0.3.0-M2</a></li>
<li><a href="release_notes_030-M1.html">0.3.0-M1</a></li>
<li><a href="release_notes_020-M1.html">0.2.0-M1</a></li>
<li><a href="release_notes_010-M3.html">0.1.0-M3</a></li>
<li><a href="release_notes_010-M1.html">0.1.0-M1</a></li>
</ul>
</li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Installation</a>
<ul>
<li><a href="installation-building.html">Building Ditto</a></li>
<li><a href="installation-running.html">Running Ditto</a></li>
<li><a href="installation-operating.html">Operating Ditto</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Basic concepts</a>
<ul>
<li><a href="basic-overview.html">Overview</a></li>
<li class="subfolders">
<a href="#"><span></span>Model entities</a>
<ul>
<li><a href="basic-thing.html">Thing</a></li>
<li><a href="basic-acl.html">Access Control List (ACL)</a></li>
<li><a href="basic-feature.html">Feature</a></li>
<li><a href="basic-policy.html">Policy</a></li>
<li><a href="basic-namespaces-and-names.html">Namespaces and Names</a></li>
<li><a href="basic-metadata.html">Thing Metadata</a></li>
<li><a href="basic-errors.html">Errors</a></li>
</ul>
</li>
<li><a href="basic-auth.html">Authentication and Authorization</a></li>
<li><a href="basic-messages.html">Messages</a></li>
<li><a href="basic-signals.html">Signals</a></li>
<li class="subfolders">
<a href="#"><span></span>Signal types</a>
<ul>
<li><a href="basic-signals-command.html">Command</a></li>
<li><a href="basic-signals-commandresponse.html">Command response</a></li>
<li><a href="basic-signals-errorresponse.html">Error response</a></li>
<li><a href="basic-signals-event.html">Event</a></li>
</ul>
</li>
<li><a href="basic-apis.html">APIs</a></li>
<li><a href="basic-connections.html">Connections</a></li>
<li><a href="basic-placeholders.html">Placeholders</a></li>
<li><a href="basic-changenotifications.html">Change notifications</a></li>
<li><a href="basic-rql.html">RQL expressions</a></li>
<li><a href="basic-enrichment.html">Signal enrichment</a></li>
<li><a href="basic-search.html">Search</a></li>
<li><a href="basic-acknowledgements.html">Acknowledgements / QoS</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Architecture</a>
<ul>
<li><a href="architecture-overview.html">Overview</a></li>
<li class="subfolders">
<a href="#"><span></span>Services</a>
<ul>
<li><a href="architecture-services-policies.html">Policies</a></li>
<li><a href="architecture-services-things.html">Things</a></li>
<li><a href="architecture-services-things-search.html">Things-Search</a></li>
<li><a href="architecture-services-connectivity.html">Connectivity</a></li>
<li><a href="architecture-services-concierge.html">Concierge</a></li>
<li><a href="architecture-services-gateway.html">Gateway</a></li>
</ul>
</li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>HTTP API</a>
<ul>
<li><a href="httpapi-overview.html">Overview</a></li>
<li><a href="httpapi-concepts.html">Concepts</a></li>
<li><a href="httpapi-search.html">Search</a></li>
<li><a href="httpapi-messages.html">Messages</a></li>
<li><a href="httpapi-protocol-bindings-websocket.html">WebSocket protocol binding</a></li>
<li><a href="httpapi-protocol-bindings-cloudevents.html">Cloud Events HTTP protocol binding</a></li>
<li><a href="httpapi-sse.html">Server sent events</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Connectivity API</a>
<ul>
<li><a href="connectivity-overview.html">Overview</a></li>
<li><a href="connectivity-manage-connections.html">Manage connections</a></li>
<li><a href="connectivity-protocol-bindings-amqp091.html">AMQP 0.9.1 protocol binding</a></li>
<li><a href="connectivity-protocol-bindings-amqp10.html">AMQP 1.0 protocol binding</a></li>
<li><a href="connectivity-protocol-bindings-mqtt.html">MQTT 3.1.1 protocol binding</a></li>
<li><a href="connectivity-protocol-bindings-mqtt5.html">MQTT 5 protocol binding</a></li>
<li><a href="connectivity-protocol-bindings-http.html">HTTP 1.1 protocol binding</a></li>
<li><a href="connectivity-protocol-bindings-kafka2.html">Kafka 2.x protocol binding</a></li>
<li><a href="connectivity-mapping.html">Payload mapping</a></li>
<li><a href="connectivity-header-mapping.html">Header mapping</a></li>
<li><a href="connectivity-tls-certificates.html">TLS certificates</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Client SDK</a>
<ul>
<li><a href="client-sdk-overview.html">Overview</a></li>
<li><a href="client-sdk-java.html">Java</a></li>
<li><a href="client-sdk-javascript.html">JavaScript</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>Ditto Protocol</a>
<ul>
<li><a href="protocol-overview.html">Overview</a></li>
<li><a href="protocol-twinlive.html">Twin/live channel</a></li>
<li><a href="protocol-specification.html">Specification</a></li>
<li><a href="protocol-specification-topic.html">Protocol topic</a></li>
<li><a href="protocol-specification-things.html">Things group</a></li>
<li class="subfolders">
<a href="#"><span></span>→ commands/events</a>
<ul>
<li><a href="protocol-specification-things-create-or-modify.html">Create/Modify</a></li>
<li><a href="protocol-specification-things-retrieve.html">Retrieve</a></li>
<li><a href="protocol-specification-things-delete.html">Delete</a></li>
<li><a href="protocol-specification-acks.html">Acknowledgements</a></li>
<li><a href="protocol-specification-errors.html">Errors</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>→ search/messages</a>
<ul>
<li><a href="protocol-specification-things-search.html">Search</a></li>
<li class="active"><a href="protocol-specification-things-messages.html">Messages</a></li>
</ul>
</li>
<li><a href="protocol-specification-policies.html">Policies group</a></li>
<li class="subfolders">
<a href="#"><span></span>→ commands/events</a>
<ul>
<li><a href="protocol-specification-policies-create-or-modify.html">Create/Modify</a></li>
<li><a href="protocol-specification-policies-retrieve.html">Retrieve</a></li>
<li><a href="protocol-specification-policies-delete.html">Delete</a></li>
</ul>
</li>
<li><a href="protocol-bindings.html">Bindings</a></li>
<li><a href="protocol-examples.html">Examples</a></li>
<li class="subfolders">
<a href="#"><span></span>→ Things examples</a>
<ul>
<li><a href="protocol-examples-creatething.html">Create a Thing</a></li>
<li><a href="protocol-examples-deletething.html">Delete a Thing</a></li>
<li><a href="protocol-examples-modifything.html">Modify a Thing</a></li>
<li><a href="protocol-examples-retrievething.html">Retrieve a Thing</a></li>
<li><a href="protocol-examples-retrievethings.html">Retrieve multiple Things</a></li>
<li><a href="protocol-examples-modifypolicyid.html">Modify the Policy ID of a Thing</a></li>
<li><a href="protocol-examples-createattributes.html">Create Attributes</a></li>
<li><a href="protocol-examples-deleteattributes.html">Delete Attributes</a></li>
<li><a href="protocol-examples-modifyattributes.html">Modify Attributes</a></li>
<li><a href="protocol-examples-retrieveattributes.html">Retrieve Attributes</a></li>
<li><a href="protocol-examples-createattribute.html">Create a single Attribute</a></li>
<li><a href="protocol-examples-deleteattribute.html">Delete a single Attribute</a></li>
<li><a href="protocol-examples-modifyattribute.html">Modify a single Attribute</a></li>
<li><a href="protocol-examples-retrieveattribute.html">Retrieve a single Attribute</a></li>
<li><a href="protocol-examples-createthingdefinition.html">Create a Definition</a></li>
<li><a href="protocol-examples-deletethingdefinition.html">Delete a Definition</a></li>
<li><a href="protocol-examples-modifythingdefinition.html">Modify a Definition</a></li>
<li><a href="protocol-examples-retrievethingdefinition.html">Retrieve a Definition</a></li>
<li><a href="protocol-examples-createfeatures.html">Create Features</a></li>
<li><a href="protocol-examples-deletefeatures.html">Delete Features</a></li>
<li><a href="protocol-examples-modifyfeatures.html">Modify Features</a></li>
<li><a href="protocol-examples-retrievefeatures.html">Retrieve Features</a></li>
<li><a href="protocol-examples-createfeature.html">Create a single Feature</a></li>
<li><a href="protocol-examples-deletefeature.html">Delete a single Feature</a></li>
<li><a href="protocol-examples-modifyfeature.html">Modify a single Feature</a></li>
<li><a href="protocol-examples-retrievefeature.html">Retrieve a single Feature</a></li>
<li><a href="protocol-examples-createdefinition.html">Create Feature Definition</a></li>
<li><a href="protocol-examples-deletedefinition.html">Delete Feature Definition</a></li>
<li><a href="protocol-examples-modifydefinition.html">Modify Feature Definition</a></li>
<li><a href="protocol-examples-retrievedefinition.html">Retrieve Feature Definition</a></li>
<li><a href="protocol-examples-createproperties.html">Create Feature Properties</a></li>
<li><a href="protocol-examples-deleteproperties.html">Delete Feature Properties</a></li>
<li><a href="protocol-examples-modifyproperties.html">Modify Feature Properties</a></li>
<li><a href="protocol-examples-retrieveproperties.html">Retrieve Feature Properties</a></li>
<li><a href="protocol-examples-createproperty.html">Create a single Property</a></li>
<li><a href="protocol-examples-deleteproperty.html">Delete a single Property</a></li>
<li><a href="protocol-examples-modifyproperty.html">Modify a single Property</a></li>
<li><a href="protocol-examples-retrieveproperty.html">Retrieve a single Property</a></li>
<li><a href="protocol-examples-createdesiredproperties.html">Create desired Feature Properties</a></li>
<li><a href="protocol-examples-deletedesiredproperties.html">Delete desired Feature Properties</a></li>
<li><a href="protocol-examples-modifydesiredproperties.html">Modify desired Feature Properties</a></li>
<li><a href="protocol-examples-retrievedesiredproperties.html">Retrieve desired Feature Properties</a></li>
<li><a href="protocol-examples-createdesiredproperty.html">Create a single desired Property</a></li>
<li><a href="protocol-examples-deletedesiredproperty.html">Delete a single desired Property</a></li>
<li><a href="protocol-examples-modifydesiredproperty.html">Modify a single desired Property</a></li>
<li><a href="protocol-examples-retrievedesiredproperty.html">Retrieve a single desired Property</a></li>
<li><a href="protocol-examples-errorresponses.html">Error responses</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#"><span></span>→ Policies examples</a>
<ul>
<li><a href="protocol-examples-policies-createpolicy.html">Create a Policy</a></li>
<li><a href="protocol-examples-policies-deletepolicy.html">Delete a Policy</a></li>
<li><a href="protocol-examples-policies-modifypolicy.html">Modify a Policy</a></li>
<li><a href="protocol-examples-policies-retrievepolicy.html">Retrieve a Policy</a></li>
<li><a href="protocol-examples-policies-modifypolicyentries.html">Modify entries</a></li>
<li><a href="protocol-examples-policies-retrievepolicyentries.html">Retrieve entries</a></li>
<li><a href="protocol-examples-policies-createpolicyentry.html">Create a single entry</a></li>
<li><a href="protocol-examples-policies-deletepolicyentry.html">Delete a single entry</a></li>
<li><a href="protocol-examples-policies-modifypolicyentry.html">Modify a single entry</a></li>
<li><a href="protocol-examples-policies-retrievepolicyentry.html">Retrieve a single entry</a></li>
<li><a href="protocol-examples-policies-modifysubjects.html">Modify subjects</a></li>
<li><a href="protocol-examples-policies-retrievesubjects.html">Retrieve subjects</a></li>
<li><a href="protocol-examples-policies-createsubject.html">Create a single subject</a></li>
<li><a href="protocol-examples-policies-deletesubject.html">Delete a single subject</a></li>
<li><a href="protocol-examples-policies-modifysubject.html">Modify a single subject</a></li>
<li><a href="protocol-examples-policies-retrievesubject.html">Retrieve a single subject</a></li>
<li><a href="protocol-examples-policies-modifyresources.html">Modify resources</a></li>
<li><a href="protocol-examples-policies-retrieveresources.html">Retrieve resources</a></li>
<li><a href="protocol-examples-policies-createresource.html">Create a single resource</a></li>
<li><a href="protocol-examples-policies-deleteresource.html">Delete a single resource</a></li>
<li><a href="protocol-examples-policies-modifyresource.html">Modify a single resource</a></li>
<li><a href="protocol-examples-policies-retrieveresource.html">Retrieve a single resource</a></li>
<li><a href="protocol-examples-policies-errorresponses.html">Error responses</a></li>
</ul>
</li>
<li><a href="protocol-examples-search.html">→ Search examples</a></li>
</ul>
</li>
<li><a href="sandbox.html">Sandbox</a></li>
<li><a href="presentations.html">Presentations</a></li>
<li><a href="glossary.html">Glossary</a></li>
<li><a href="feedback.html">Feedback</a></li>
<p class="external">
<a href="#" id="collapseAll">Collapse All</a> | <a href="#" id="expandAll">Expand All</a>
</p>
</ul>
<!-- this highlights the active parent class in the sidebar. this is critical so that the parent expands when you're viewing a page. This must appear below the sidebar code above. Otherwise, if placed inside customscripts.js, the script runs before the sidebar code runs and the class never gets inserted.-->
<script>$("li.active").parents('li').toggleClass("active");
</script>
</div>
<!-- Content Column -->
<div class="col-md-9" id="tg-sb-content">
<div class="post-header">
<h1 class="post-title-main">Things - Messages protocol specification</h1>
</div>
<div class="post-content">
<!-- this handles the automatic toc. use ## for subheads to auto-generate the on-page minitoc. if you use html tags, you must supply an ID for the heading element in order for it to appear in the minitoc. -->
<script>
$( document ).ready(function() {
// Handler for .ready() called.
$('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3,h4' });
/* this offset helps account for the space taken up by the floating toolbar. */
$('#toc').on('click', 'a', function() {
var target = $(this.getAttribute('href'))
, scroll_target = target.offset().top
$(window).scrollTop(scroll_target - 10);
return false
})
});
</script>
<div id="toc"></div>
<p>Messages within the Ditto Protocol allow sending, receiving and responding to
Messages. They contain an arbitrary <em>payload</em>, so you can choose what content
fits your solution best. If you want to learn more about the basic concepts of the Messages
functionality, please have a look at the <a href="basic-messages.html">Messages page</a>.</p>
<div class="alert alert-success" role="alert"><i class="fa fa-check-square-o"></i> <b>Tip:</b> If you only need to send Messages, but don’t need to receive
or respond, you could also use the <a href="httpapi-messages.html">HTTP Messages API</a></div>
<h2 id="messages-protocol">Messages protocol</h2>
<p>The Messages protocol is part of the <a href="protocol-specification.html">Ditto Protocol</a> and therefore
conforms to its specification. This section describes how the protocol envelope can be filled
for sending Messages. If you want to jump right into using the API, head over to the
next section that describes how to <a href="#using-the-messages-api">use the messages API</a>.</p>
<p>There are three protocol parameters that have special meaning for Messages:</p>
<ul>
<li><code class="highlighter-rouge">topic</code> : <em>{namespace}</em>/<em>{thingId}</em>/things/live/messages/<em>{messageSubject}</em></li>
<li><code class="highlighter-rouge">path</code> : <em>{addressedPartOfThing}</em>/<em>{mailbox}</em>/messages/<em>{messageSubject}</em></li>
<li><code class="highlighter-rouge">headers</code> : The headers for Messages must include <em>content-type</em></li>
</ul>
<p><br /></p>
<p>The <code class="highlighter-rouge">topic</code> definition for Messages needs the <em>namespace</em> and <em>thingId</em>
of the Thing you’re sending Messages to. The <em>messageSubject</em> describes the Message
and must conform to the <em>path</em> as described in <a href="https://tools.ietf.org/html/rfc3986">RFC-3986</a>.
Examples for valid topics are:</p>
<ul>
<li><code class="highlighter-rouge">org.eclipse.ditto/smartcoffee/things/live/messages/ask/question</code></li>
<li><code class="highlighter-rouge">com.example/smarthome/things/live/messages/turnoff</code></li>
</ul>
<p><br /></p>
<p>The <code class="highlighter-rouge">path</code> also contains the <em>messageSubject</em> that describes the Message.
<em>mailbox</em> can be <em>inbox</em> (Message is sent to a Thing) or <em>outbox</em> (Message is
sent from a Thing). The <em>addressedPartOfThing</em> tells which part of the Thing
is addressed. <code class="highlighter-rouge">/features/water-tank</code> would address the water-tank Feature of
the Thing, while `` would address the whole Thing. Valid paths are e.g.:</p>
<ul>
<li><code class="highlighter-rouge">/inbox/messages/ask/question</code></li>
<li><code class="highlighter-rouge">/features/lights/inbox/messages/turnoff</code></li>
<li><code class="highlighter-rouge">/features/smokedetector/outbox/messages/smokedetected</code></li>
</ul>
<p><br /></p>
<p>In the <code class="highlighter-rouge">headers</code> of the envelope the Messages API requires:</p>
<ul>
<li><code class="highlighter-rouge">content-type</code> : The type of the payload you are sending, e.g. <em>text/plain</em></li>
</ul>
<h2 id="using-the-messages-api">Using the Messages API</h2>
<p>The following parts contain examples that will show you how to leverage the Messages API.
In the examples we will use some kind of smart coffee machine with the id <em>smartcoffee</em>.</p>
<div class="alert alert-info" role="alert"><i class="fa fa-info-circle"></i> <b>Note:</b> We encourage you to play around with the examples. You can use
the WebSocket binding to do so. Make sure the Thing you are sending Messages to is existing and has
the correct access rights.</div>
<h3 id="sending-a-message-to-a-thing">Sending a Message to a Thing</h3>
<p>When sending a Message to a Thing, we send it to the inbox of the receiving entity.<br />
What follows is a simple example Message that asks our Thing <em>smartcoffee</em> how it is feeling today:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto/smartcoffee/things/live/messages/ask"</span><span class="p">,</span><span class="w">
</span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"content-type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"text/plain"</span><span class="p">,</span><span class="w">
</span><span class="s2">"correlation-id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"a-unique-string-for-this-message"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/inbox/messages/ask"</span><span class="p">,</span><span class="w">
</span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Hey, how are you?"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>Notice that our <code class="highlighter-rouge">topic</code> adheres to the <a href="protocol-specification-topic.html">Ditto Protocol topic definition</a>
with <em>messages</em> as the criterion, <em>live</em> as channel, and the message-subject as action.</p>
<p>We encourage you to always send a <code class="highlighter-rouge">correlation-id</code> with your Messages.
This is especially important, since the WebSocket Ditto Protocol binding
sends messages in a fire-and-forget manner. Ditto wouldn’t know who to
respond to if there was no <code class="highlighter-rouge">correlation-id</code> set in the Message.</p>
<div class="alert alert-success" role="alert"><i class="fa fa-check-square-o"></i> <b>Tip:</b> If you want to receive the response to
a Message, make sure to always send a <code class="highlighter-rouge">correlation-id</code> with it.</div>
<p>The response we would get from our coffee machine could look something like this:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto/smartcoffee/things/live/messages/ask"</span><span class="p">,</span><span class="w">
</span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"correlation-id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"a-unique-string-for-this-message"</span><span class="p">,</span><span class="w">
</span><span class="s2">"auth-subjects"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"ditto"</span><span class="p">,</span><span class="w"> </span><span class="s2">"nginx:ditto"</span><span class="p">],</span><span class="w">
</span><span class="s2">"content-type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"text/plain"</span><span class="p">,</span><span class="w">
</span><span class="s2">"version"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/outbox/messages/ask"</span><span class="p">,</span><span class="w">
</span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"I do not know, since i am only a coffee machine."</span><span class="p">,</span><span class="w">
</span><span class="s2">"status"</span><span class="p">:</span><span class="w"> </span><span class="mi">418</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>The answer of the coffee machine has the same <code class="highlighter-rouge">topic</code> and <code class="highlighter-rouge">correlation-id</code>
as the original message. As we can see, the response does not only contain a
<code class="highlighter-rouge">value</code> but also the <code class="highlighter-rouge">status</code> of the response
which is based on the <a href="protocol-specification.html#status">HTTP status codes</a>.
Notice, that the <code class="highlighter-rouge">path</code> of the Message has changed from <em>inbox</em> to <em>outbox</em>,
which means the Message was sent <em>from</em> the Thing.
Ditto automatically added some headers that we can ignore for now.</p>
<h3 id="receiving-a-message">Receiving a message</h3>
<p>To be able to show how to receive Messages, we need to use one of the provided Ditto Protocol
bindings. We will use the WebSocket binding for now. With it, it is amazingly easy to
receive Messages sent <em>to</em> or <em>from</em> Things. You only need to fulfill these <em>three</em> simple requirements:</p>
<ol>
<li>Having an open connection to the Ditto WebSocket</li>
<li>Having sent the <a href="httpapi-protocol-bindings-websocket.html#request-events">WebSocket binding specific message</a>
<code class="highlighter-rouge">START-SEND-MESSAGES</code> to the WebSocket to be able to retrieve Messages</li>
<li>You are allowed (<a href="basic-auth.html">authorized</a>) to receive Messages</li>
</ol>
<p>If we have a user <em>ditto</em> that has <code class="highlighter-rouge">READ</code> permission on <em>smartcoffee</em>, we could receive Messages
for it using a local Ditto instance using simple JavaScript:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// connect to the WebSocket</span>
<span class="kd">var</span> <span class="nx">websocket</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocket</span><span class="p">(</span><span class="s1">'ws://ditto:ditto@localhost:8080/ws/1'</span><span class="p">);</span>
<span class="nx">websocket</span><span class="p">.</span><span class="nx">onmessage</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'received message data: '</span> <span class="o">+</span> <span class="nx">message</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
<span class="p">});</span>
<span class="nx">websocket</span><span class="p">.</span><span class="nx">onopen</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">ws</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// register for receiving messages</span>
<span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="s1">'START-SEND-MESSAGES'</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>
<p>If we would send the Message described in <a href="#sending-a-message-to-a-thing">Sending a Message to a Thing</a>
to the WebSocket, our JavaScript receiver would receive the following data:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto/smartcoffee/things/live/messages/ask"</span><span class="p">,</span><span class="w">
</span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"correlation-id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"demo-6qaal9l"</span><span class="p">,</span><span class="w">
</span><span class="s2">"auth-subjects"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"ditto"</span><span class="p">,</span><span class="w"> </span><span class="s2">"nginx:ditto"</span><span class="p">],</span><span class="w">
</span><span class="s2">"content-type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"text/plain"</span><span class="p">,</span><span class="w">
</span><span class="s2">"version"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/inbox/messages/ask"</span><span class="p">,</span><span class="w">
</span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Hey, how are you?"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>The content is almost the same, except for automatically added headers that we can ignore.
In the next part you can learn how to respond to this Message.</p>
<h3 id="responding-to-a-message">Responding to a Message</h3>
<p>After <a href="#sending-a-message-to-a-thing">sending a Message to a Thing</a> and
<a href="#receiving-a-message">receiving the Message</a>, we are able to respond to the
Message we received. To do this, we can re-use the relevant Message contents
and change the type from incoming to outgoing. Here is a simple JavaScript
function that shows how you could respond to a given Message. It takes
the original Message, the response payload and status code and returns the
response Message you can send using a Ditto Protocol binding.</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">createTextResponse</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">originalMessage</span><span class="p">,</span> <span class="nx">payload</span><span class="p">,</span> <span class="nx">statusCode</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">topic</span> <span class="o">=</span> <span class="nx">originalMessage</span><span class="p">.</span><span class="nx">topic</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">correlationId</span> <span class="o">=</span> <span class="nx">originalMessage</span><span class="p">.</span><span class="nx">headers</span><span class="p">[</span><span class="s2">"correlation-id"</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">outboxPath</span> <span class="o">=</span> <span class="nx">originalMessage</span><span class="p">.</span><span class="nx">path</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="s2">"inbox"</span><span class="p">,</span> <span class="s2">"outbox"</span><span class="p">);</span>
<span class="k">return</span> <span class="p">{</span>
<span class="s2">"topic"</span><span class="p">:</span> <span class="nx">topic</span><span class="p">,</span>
<span class="s2">"headers"</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">"correlation-id"</span><span class="p">:</span> <span class="nx">correlationId</span><span class="p">,</span>
<span class="s2">"content-type"</span><span class="p">:</span> <span class="s2">"text/plain"</span>
<span class="p">},</span>
<span class="s2">"path"</span><span class="p">:</span> <span class="nx">outboxPath</span><span class="p">,</span>
<span class="s2">"status"</span><span class="p">:</span> <span class="nx">statusCode</span><span class="p">,</span>
<span class="s2">"value"</span><span class="p">:</span> <span class="nx">payload</span>
<span class="p">};</span>
<span class="p">};</span>
</code></pre></div></div>
<p>With this method you could create a simple text response, and send it
using e.g. the WebSocket binding. Since the original Message and the response
Message have the same <code class="highlighter-rouge">correlation-id</code>, the issuer would receive your response:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto/smartcoffee/things/live/messages/ask"</span><span class="p">,</span><span class="w">
</span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"correlation-id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"demo-6qaal9l"</span><span class="p">,</span><span class="w">
</span><span class="s2">"auth-subjects"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"ditto"</span><span class="p">,</span><span class="w"> </span><span class="s2">"nginx:ditto"</span><span class="p">],</span><span class="w">
</span><span class="s2">"content-type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"text/plain"</span><span class="p">,</span><span class="w">
</span><span class="s2">"version"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/outbox/messages/ask"</span><span class="p">,</span><span class="w">
</span><span class="s2">"status"</span><span class="p">:</span><span class="w"> </span><span class="mi">418</span><span class="p">,</span><span class="w">
</span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"I don't know since i am only a coffee machine"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h3 id="talking-to-features">Talking to Features</h3>
<p>When sending Messages to or from Features, almost everything stays the same as with
Things. The <code class="highlighter-rouge">path</code> in the JSON and an additional <code class="highlighter-rouge">feature-id</code> header are the only parts to change.
A Message to a Feature could therefore have the following JSON:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto/smartcoffee/things/live/messages/heatUp"</span><span class="p">,</span><span class="w">
</span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"content-type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"text/plain"</span><span class="p">,</span><span class="w">
</span><span class="s2">"correlation-id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"a-unique-string-for-this-message"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/features/water-tank/inbox/messages/heatUp"</span><span class="p">,</span><span class="w">
</span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"47"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h3 id="sending-and-handling-claim-messages">Sending and handling Claim Messages</h3>
<p>Claim Messages are handled like standard Messages with the difference that the message subject is <em>claim</em> and they
can only be sent to a Thing. As the purpose of claiming is to gain access to a Thing, you do not require <code class="highlighter-rouge">WRITE</code>
permission to send a Claim Message to a Thing. This however means for a receiver that incoming Claim Messages have to be
carefully verified before granting access to a Thing.</p>
<p>A Claim Message to gain access to our smart coffee machine might look like this:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto/smartcoffee/things/live/messages/claim"</span><span class="p">,</span><span class="w">
</span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"content-type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"text/plain"</span><span class="p">,</span><span class="w">
</span><span class="s2">"correlation-id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"a-unique-string-for-this-claim-message"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/inbox/messages/claim"</span><span class="p">,</span><span class="w">
</span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"some-claiming-secret"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>After verifying the Message, in particular the correctness of the payload, the smart coffee machine could grant access
to the issuer by setting an additional permission and respond with a <em>status</em> of <code class="highlighter-rouge">200</code> or <code class="highlighter-rouge">204</code> (as you can see the
<code class="highlighter-rouge">path</code> changed to <em>outbox</em> and the <code class="highlighter-rouge">direction</code> is now <em>from</em>, same as above for the Thing Message):</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org.eclipse.ditto/smartcoffee/things/live/messages/claim"</span><span class="p">,</span><span class="w">
</span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"content-type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"text/plain"</span><span class="p">,</span><span class="w">
</span><span class="s2">"correlation-id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"a-unique-string-for-this-claim-message"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/outbox/messages/claim"</span><span class="p">,</span><span class="w">
</span><span class="s2">"status"</span><span class="p">:</span><span class="w"> </span><span class="mi">204</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>In case the Claim Message does not contain the required information the smart coffee machine can reject the
claim request by <em>NOT</em> granting access and responding with a status different from <code class="highlighter-rouge">200</code> or <code class="highlighter-rouge">204</code>.</p>
<div class="tags">
<b>Tags: </b>
<a href="tag_protocol.html" class="btn btn-default navbar-btn cursorNorm" role="button">protocol</a>
</div>
</div>
<hr class="shaded"/>
<footer>
<div class="row">
<div class="col-lg-12 footer">
<div class="logo">
<a href="https://eclipse.org"><img src="images/eclipse_foundation_logo.svg" alt="Eclipse logo"/></a>
</div>
<p class="notice">
&copy;2021 Eclipse Ditto.
Site last generated: May 6, 2021 <br />
</p>
<div class="quickLinks">
<a href="https://www.eclipse.org/legal/privacy.php" target="_blank">
&gt; Privacy Policy
</a>
<a href="https://www.eclipse.org/legal/termsofuse.php" target="_blank">
&gt; Terms of Use
</a>
<a href="https://www.eclipse.org/legal/copyright.php" target="_blank">
&gt; Copyright Agent
</a>
<a href="https://www.eclipse.org/legal" target="_blank">
&gt; Legal
</a>
<a href="https://www.eclipse.org/legal/epl-2.0/" target="_blank">
&gt; License
</a>
<a href="https://eclipse.org/security" target="_blank">
&gt; Report a Vulnerability
</a>
</div>
</div>
</div>
</footer>
</div>
<!-- /.row -->
</div>
<!-- /.container -->
</div>
<!-- /#main -->
</div>
</body>
</html>