w3c / wot-thing-description

Web of Things (WoT) Thing Description
http://w3c.github.io/wot-thing-description/
Other
131 stars 63 forks source link

Describing a single WebSocket endpoint shared by multiple Things #1664

Open benfrancis opened 2 years ago

benfrancis commented 2 years ago

Further to the issue of how to describe a single WebSocket used by all operations on a Thing (see #1070 and #878), I'd like to introduce an additional use case where a single WebSocket endpoint is shared between multiple Things.

Use Case: A cloud service monitors data from buildings in order to store time-series data and generate analytics about how the buildings are being used.

Using the approach described in https://github.com/w3c/wot-thing-description/issues/1070#issuecomment-1215269329 I believe it's possible to describe a single WebSocket endpoint for a Thing over which all property changes (observeproperty) and events (subscribeevent) can be sent. This still requires a separate WebSocket connection for every device in the building, e.g.

For a building with hundreds of sensors, this will not scale very well.

It would be more efficient if the cloud service could maintain a single WebSocket connection with each building, over which all the events and property changes for all of the Things it exposes are streamed. E.g.

Apart from WebThings Gateway which already provides this kind of single WebSocket endpoint, another real world example of this is the Urban Observatory API for the Urban Sciences Building at Newcastle University in the UK. There is a streaming API for this building which streams all changes in all properties over a single WebSocket connection in real time https://api.usb.urbanobservatory.ac.uk/live/

I can generate Thing Descriptions for each device, with a single WebSocket endpoint per device, but how would you go about describing the building as a whole and the top level endpoint for monitoring the whole building over a single connection?


A starting point might be the ThingDirectory schema and Directory Service API from the WoT Discovery specification, which provide way to describe and interact with a collection of Things. However, that API only provides access to the metadata (Thing Descriptions) of Things, not their data (via protocol bindings). Each Thing must be interacted with separately using the protocol bindings in their individual Thing Descriptions, which may come from different origins using different protocols.

In the case of a Web of Things Gateway which hosts the Thing Descriptions and API endpoints of a whole collection of Things itself, how could I describe a WebSocket endpoint on that gateway over which any operation can be carried out on any of the Things it exposes?

Some ideas that come to mind for describing this endpoint in a Thing Description of the gateway:

{
  "@type": "ThingDirectory",
  ...
  "forms": [
    {
      "href": "wss://mybuilding.com",
      "subprotocol": "webthing-gateway",
      "op": "?"
    }
  ]
}
{
  "@type": "ThingDirectory",
  ...
  "links": [
    {
      "href": "wss://mybuilding.com",
      "rel": "?"
    }
  ]
}
{
  "@type": "ThingDirectory",
  ...
  "actions": {
    "subscribeToEventOfThing": {
      "input": {
        "type": "object",
        "properties": {
          "thingId": {"type": "string"},
          "eventName": {"type", "string"},
        }
      },
      "forms": [
        {
          "href": "wss://mybuilding.com",
          "subprotocol": "webthing-gateway",
          "op": "invokeaction"
        }
      ]
    },
    "observePropertyOfThing": {
      "input": {
        "type": "object",
        "properties": {
          "thingId": {"type": "string"},
          "propertyName": {"type", "string"},
        }
      },
      "forms": [
        {
          "href": "wss://mybuilding.com",
          "subprotocol": "webthing-gateway",
          "op": "invokeaction"
        }
      ]
    }
  }
}

How would you model this in a Thing Description?

benfrancis commented 2 years ago

Thinking about this some more, I'm really struggling to think of a way to describe this single WebSocket endpoint which acts as a kind of proxy to other Things in a Thing Description.

Following the same logic as for multiple interaction affordances sharing the same WebSocket endpoint discussed in https://github.com/w3c/wot-thing-description/issues/1070#issuecomment-1215269329, perhaps another approach is to simply:

Having to parse every Form of every InteractionAffordance of every Thing is far less efficient than parsing a single Form of a single Thing, but it works around the problem of trying to describe a single proxy endpoint by just pooling connections instead. It also allows for more flexibility in Thing Descriptions where only a subset of InteractionAffordances may be available via the WebSocket endpoint.

What do you think?

egekorkan commented 2 years ago

There are some previous discussions on this, I would hope to tackle them all in one shot in the next spec version

benfrancis commented 2 years ago

I would hope to tackle them all in one shot in the next spec version

I agree, but it would also be good to get feedback from people on how you would model this in Thing Description 1.1, for those of us who can't wait ~2 years for the next version :)

lu-zero commented 1 year ago

Having to parse every Form of every InteractionAffordance of every Thing is far less efficient than parsing a single Form of a single Thing, but it works around the problem of trying to describe a single proxy endpoint by just pooling connections instead. It also allows for more flexibility in Thing Descriptions where only a subset of InteractionAffordances may be available via the WebSocket endpoint.

In 1.1 you may (ab)use the security layer and define how much of the path has to be multiplexed there and then describe the forms as if they weren't multiplexed. A consumer that doesn't care then uses the non-multiplexed path, the consumer that knows about that "security" layer can opt to use it and rely on the information there to go from non-multiplexed to multiplexed.

You probably want to always have a fallback consumers that do not grok multiplexed websocket would rather use anyway.

benfrancis commented 1 year ago

@lu-zero Interesting. Can you provide an example, because I'm not exactly clear on how that mechanism would work.

How would it be different than a Consumer just knowing to re-use WebSocket connections to the same URL?

Security does add complexity here, since it's technically possible that the same Consumer might open multiple WebSockets using different security credentials which provide access to a different sub-set of Things.

lu-zero commented 1 year ago

Currently the Security elements are the only ones that apply an arbitrary transformation to the href present in the form.

That assuming you want to be able to degrade that way. Alternatively you extend the protocol binding with a subprotocol + custom element, I guess?