GithubHelp home page GithubHelp logo

Comments (12)

benfrancis avatar benfrancis commented on July 19, 2024 1

AWS IoT and Azure IoT both provide APIs using MQTT over WebSockets. (Azure IoT also provides AMQP over WebSockets).

from api.

benfrancis avatar benfrancis commented on July 19, 2024 1

For just subscribing to events I think Server Sent Events could actually be a good solution (and could probably be shimmed on the client using the Fetch API where it isn't supported). But I think we really need a bi-directional realtime communication mechanism.

If we only want to have one WebSocket open per Thing and use it for multiple purposes then it may be inevitable that we have to either use an existing protocol like MQTT or create a simple Web Thing sub-protocol for WebSockets in order to create the necessary semantics.

Here are some example messages for a simple Web Thing WebSocket sub-protocol...

Client to Thing

{
  "messageType": "setProperty":
  "data": {
    "leftMotor": 100
  }
}
{
  "messageType": "requestAction",
  "data": {
    "goForward": {},
  }
}
{
  "messageType": "subscribeEvent",
  "data": {
    "motion": {}
  }
}

Thing to Client

{
  "messageType: propertyStatus",
  "data": {
    "led": true
  }
}
{
  "messageType": "actionStatus",
  "data": {
    "grab": {
      "href": "/actions/123e4567-e89b-12d3-a456-426655",
      "status": "completed"
    }
  }
}
{
  "messageType": "event":
  "data": {
    "motion": {
      "time": "2017-01-24T13:02:45+00:00"
    }
  }
}

We could also add a "thing" property to the messages which specifies which Thing it refers to (by the Thing's URL) so that a client could open a single WebSocket for multiple Things on a gateway.

from api.

benfrancis avatar benfrancis commented on July 19, 2024

I'm starting to wonder whether you should just open one WebSocket per Thing...

GET /things/myThing
Upgrade: websocket
...

With the option of subscribing to all things...

GET /things
Upgrade: websocket
...

Or a subset of things

GET /things/?type=onOffSwitch
Upgrade: websocket
...

If you're subscribing to a whole Thing rather than just a single property, the challenge is then how to do that without having to invent a whole pub/sub sub-protocol to use over WebSockets and keep it feeling like a natural extension of REST (like CoAP has), rather than a completely separate API.

For example, when a property changes would you send the whole Thing description including property values down the WebSocket, or some sort of "property changed" message?

from api.

benfrancis avatar benfrancis commented on July 19, 2024

One interesting solution I came across is how Firebase does "REST streaming" using the EventSource/Server-Sent Events protocol. This is used on the back end of the "REST Streaming" in Nest's cloud API.

You can subscribe to a text/event-stream with "put" and "patch" messages to keep you up to date with changes.

I'm not sure of the mechanics of how the streaming part actually works, although I guess you could use the same protocol as a sub-protocol of WebSockets. This would allow you to have just one open WebSocket for multiple resources, in a somewhat RESTful way.

from api.

benfrancis avatar benfrancis commented on July 19, 2024

The Web Thing Model has the concept of "subscriptions".

You can create a new subscription with a GET request which has a Upgrade and Callback headers. the Upgrade header specifies the websocket or webhook protocol and the Callback header specifies a URL to use as a callback (required for webhook). The server then response with 101 Switching Protocol for a WebSocket or 200 OK for a WebHook. It then also adds a subscription resource to a list of subscriptions with URLs you can GET and DELETE to cancel.

I like the idea of subscription resources, but the WebSocket mechanism has the problem of not scaling well for multiple subscriptions as it appears to open a WebSocket per subscription.

from api.

benfrancis avatar benfrancis commented on July 19, 2024

I've made a first pass on a Web Thing WebSocket API in 7d7f03e

This approach uses a single WebSocket per thing and defines six simple message types (very close to the above) as a start on a "webthing" subprotocol for WebSockets.

You can see the new Web Thing WebSocket API section of the spec here.

This commit also added a "links" section to the Web Thing Description which provides a link to the WebSocket URL for a Thing, as well as its Properties, Actions and Events resources (fixes #13).

Feedback welcome.

from api.

hobinjk avatar hobinjk commented on July 19, 2024

@benfrancis What should happen if a WebSocket client sends a "setProperty" message referring to a nonexistent property? I believe the behavior that makes the most sense is to echo the HTTP API by responding with some kind of error message like

{
  "messageType": "error",
  "data": {
      "message": "Property does not exist"
   }
}

It could also include a code as per #27. What do you think?

from api.

benfrancis avatar benfrancis commented on July 19, 2024

Good question.

I think currently an HTTP PUT on a non-existent property returns a "400 Bad Request" response. I guess it's up to us how we map this onto the WebSocket protocol.

{
  "messageType": "error",
  "data": {
      "status": "400 Bad Request",
      "message": "Property does not exist"
   }
}

looks sensible.

My only concern would be whether the client will know which "request" this "response" refers to! This is WebSockets are such a pain, we have to invent a whole new protocol.

from api.

hobinjk avatar hobinjk commented on July 19, 2024

It might be nice to include the originating request in the error message as context like

{
  "messageType": "error",
  "data": {
      "status": "400 Bad Request",
      "message": "Property does not exist",
      "request": {
          "messageType": "setProperty",
          "data": {
            "nonexistentproperty": 1323
          }
      }
   }
}

This would allow a client to include a request id in their message if they care about reliability

from api.

hobinjk avatar hobinjk commented on July 19, 2024

Although I'm not sure how to handle a setProperty message with a mix of valid and invalid properties

from api.

coderbyheart avatar coderbyheart commented on July 19, 2024

Subscribing to one Thing or all Things is most likely the best choice, not individual properties.

Especially since Things will not be sending all sensor data all the time because this consumes a lot of energy and resources. For Bluetooth Low Energy devices there is this concept of notifications for characteristics which are enabled/disabled by the central. Only if enabled, the peripheral will notify the central about a changed value or a current measure (e.g. temperature measure will be constantly published regardless whether the value has changed).

For a device like this, the notification feature would be exposed as a boolean property using WoT, which clients can enabled in order for the device to start publishing propertyStatus events on the websocket.

from api.

hobinjk avatar hobinjk commented on July 19, 2024

I think it makes sense to have a device be in a low power poll-only mode by default and have it spin up into the notifying mode only when a websocket is open. This can further be enhanced by allowing the WoT provider to elect to not support websockets and remain in low power mode always.

We can use the act of opening a websocket to signify a desire to start doing low latency, high power communication with the device.

from api.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.