Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Describe Gateway /things websocket endpoint #142

Open
wants to merge 2 commits into
base: gh-pages
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 48 additions & 11 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ <h3><code>Thing</code> resource</h3>
<div class="example-title marker">
<span>Request</span>
</div>
<pre>GET http://mythingserver.com/things/pi
<pre>GET http://mywebthingserver.com/things/pi
Accept: application/json</pre>
</div>
<div class="example">
Expand Down Expand Up @@ -445,7 +445,7 @@ <h3><code>Properties</code> resource</h3>
<div class="example-title marker">
Request
</div>
<pre>GET http://mythingserver.com/things/pi/properties
<pre>GET http://mywebthingserver.com/things/pi/properties
Accept: application/json</pre>
</div>
<div class="example">
Expand All @@ -470,7 +470,7 @@ <h3><code>Property</code> resource</h3>
<div class="example-title marker">
Request
</div>
<pre>GET http://mythingserver.com/things/pi/properties/temperature
<pre>GET http://mywebthingserver.com/things/pi/properties/temperature
Accept: application/json</pre>
</div>
<div class="example">
Expand All @@ -487,7 +487,7 @@ <h3><code>Property</code> resource</h3>
<div class="example-title marker">
Request
</div>
<pre>PUT http://mythingserver.com/things/pi/properties/led
<pre>PUT http://mywebthingserver.com/things/pi/properties/led
{
"led": true
}
Expand All @@ -510,7 +510,7 @@ <h3><code>Actions</code> resource</h3>
<p>Any action supported by the thing can be requested via this top level action queue. If an unsupported action type is requested, the server should respond with a <code>400 Bad Request</code> response.</p>
<p><strong>Action Request</strong></p>
<pre class="example" title="Request an action">
POST https://mythingserver.com/things/lamp/actions/
POST https://mywebthingserver.com/things/lamp/actions/
Accept: application/json

{
Expand Down Expand Up @@ -573,7 +573,7 @@ <h3><code>Action</code> resource</h3>
<p>If a client tries to request an action of another type via this resource, the server should respond with a <code>400 Bad Request</code> response.</p>
<p><strong>Action Request</strong></p>
<pre class="example" title="Request an action">
POST https://mythingserver.com/things/lamp/actions/fade
POST https://mywebthingserver.com/things/lamp/actions/fade
Accept: application/json

{
Expand Down Expand Up @@ -784,17 +784,17 @@ <h3>Alternative Protocol Bindings</h3>
</section>
<section>
<h2>Web Thing WebSocket API</h2>
<p>The Web Thing WebSocket API complements the REST API to provide a realtime mechanism to make multiple requests and be notified of events as soon as they happen, by keeping a WebSocket [[!WEBSOCKETS-PROTOCOL]] open on the Web Thing. The "webthing" WebSocket subprotocol defined here has a simple set of message types and a JSON response format consistent with the Web Thing REST API.</p>
<p>The Web Thing WebSocket API complements the REST API to provide a realtime mechanism to make multiple requests and be notified of events as soon as they happen, by keeping a WebSocket [[!WEBSOCKETS-PROTOCOL]] open on the Web Thing. The "webthing" WebSocket subprotocol defined here has a simple set of message types and a JSON response format consistent with the Web Thing REST API. Each message may additionally include an <code>id</code> member set to the <code>id</code> of the thing producing the message.</p>
<section>
<h3>Protocol Handshake</h3>
<p>To open a WebSocket on a Thing, an HTTP GET request is upgraded to a WebSocket using a standard WebSocket protocol handshake [[!WEBSOCKETS-PROTOCOL]] and the "webthing" subprotocol. The WebSocket URL for a Web Thing is specified in the links member of the Web Thing Description.</p>
<div class="example">
<div class="example-title marker">
Request
</div>
<pre>GET wss://mythingserver.com/things/robot
Host: mythingserver.com
Origin: https://mythingserver.com
<pre>GET wss://mywebthingserver.com/things/robot
Host: mywebthingserver.com
Origin: https://mywebthingserver.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Expand All @@ -816,7 +816,7 @@ <h3>Protocol Handshake</h3>
<div class="example-title marker">
Example
</div>
<pre>const socket = new WebSocket('wss://mywebthingserver/things/robot', 'webthing');</pre>
<pre>const socket = new WebSocket('wss://mywebthingserver.com/things/robot', 'webthing');</pre>
</div>
</section>
<section>
Expand All @@ -827,6 +827,7 @@ <h3><code>setProperty</code> message</h3>
Example
</div>
<pre>{
"id": "https://mywebthingserver.com/things/robot",
"messageType": "setProperty",
"data": {
"leftMotor": 100
Expand All @@ -842,6 +843,7 @@ <h3><code>requestAction</code> message</h3>
Example
</div>
<pre>{
"id": "https://mywebthingserver.com/things/robot",
"messageType": "requestAction",
"data": {
"goForward": {},
Expand All @@ -857,6 +859,7 @@ <h3><code>addEventSubscription</code> message</h3>
Example
</div>
<pre>{
"id": "https://mywebthingserver.com/things/robot",
"messageType": "addEventSubscription",
"data": {
"motion": {}
Expand All @@ -872,6 +875,7 @@ <h3><code>propertyStatus</code> message</h3>
Example
</div>
<pre>{
"id": "https://mywebthingserver.com/things/robot",
"messageType": "propertyStatus",
"data": {
"led": true
Expand All @@ -887,6 +891,7 @@ <h3><code>actionStatus</code> message</h3>
Example
</div>
<pre>{
"id": "https://mywebthingserver.com/things/robot",
"messageType": "actionStatus",
"data": {
"grab": {
Expand All @@ -907,6 +912,7 @@ <h3><code>event</code> message</h3>
Example
</div>
<pre>{
"id": "https://mywebthingserver.com/things/robot",
"messageType": "event",
"data": {
"motion": {
Expand All @@ -917,6 +923,37 @@ <h3><code>event</code> message</h3>
</div>
</section>
</section>
<section>
<h2>Gateway WebSocket API</h2>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be a separate section of the specification. It should all be part of the Web Thing WebSocket API section, which may eventually become a separate W3C "Web Thing Protocol" specification to define a webthing WebSocket sub-protocol.

<p>The Gateway WebSocket API acts as a broader version of the <a href="#web-thing-websocket-api">Web Thing WebSocket API</a> by allowing the client to open one WebSocket connection per Gateway instead of per Thing. The connection then acts as a multiplex of all the Gateway's Things' WebSocket connections. The <code>id</code> member is required for this channel to allow both the Gateway and the WebSocket client to determine with which Thing each message is associated.
<section>
<h3>Protocol Handshake</h3>
<p>To open a WebSocket on a Gateway, an HTTP GET request is upgraded to a WebSocket using a standard <a href="https://tools.ietf.org/html/rfc6455">WebSocket protocol</a> handshake and the "webthing" subprotocol. The WebSocket URL for a Gateway is the "/things" endpoint.</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that in section 3 it says "The specific URLs and URL structure of resources are defined by the Thing Description. This specification does not define a fixed URL structure."

It's important that the specification does not rely on hard coded paths like "/things" but instead has endpoints which can be dynamically discovered by a WoT client using any URL structure.

This section makes me realise that while WebSocket endpoints for individual devices can be discovered through the links section of a Thing resource, and a Thing resource can be discovered through links in the Things resource, there is no explicit mechanism for discovering the Things resource itself. We are assigning special behaviour to a resource just because it is called /things.

In Whistler we discussed an alternative approach to this where we treat the gateway itself as a web thing, with a gateway capability schema, and link to the things it manages via its own links member.

If we took this approach we could also provide a gateway-wide WebSocket endpoint in the links member of the gateway's Thing Description. This would ensure that once a client has the URL of the gateway's Thing Description it can discover the WebSocket endpoint directly, without having to rely on a hard coded path.

This approach also has the benefit of being able to define actions on the gateway itself such as "pair", "unpair" and "reboot".

<div class="example">
<div class="example-title marker">
Request
</div>
<pre>GET wss://mywebthingserver.com/things
Host: mywebthingserver.com
Origin: https://mywebthingserver.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: webthing
Sec-WebSocket-Version: 13</pre>
</div>
<div class="example">
<div class="example-title marker">
Response
</div>
<pre>HTTP 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: webthing</pre>
</div>
</section>
</section>
<section>
<h2>Further Information</h2>
<p><a href="https://docs.google.com/document/d/1H3coHbb3Bwd02_NJi4KEBONByUkq92_HsTk1IpfmACY/edit?usp=sharing">Web of Things Integration Patterns</a><br />
Expand Down