Allow pushing WS messages directly to addons#3291
Allow pushing WS messages directly to addons#3291flatsiedatsie wants to merge 2 commits intoWebThingsIO:masterfrom
Conversation
This avoids addons having to create a new websocket to get things data that is already being received in the browser window.
|
(The Candle controller also has a gateway variety, which is a bit simpler: https://github.com/flatsiedatsie/photo-frame/blob/7a53a382850cbd3fafa1cffeb259176c5a523c38/js/extension.js#L34) |
|
Strange, I ran prettier. |
|
Could you maybe start by explaining the use case in the form of a user story in a new GitHub issue? What are you trying to achieve? It seems like you maybe want client-side JavaScript in an extension add-on to be notified when some state of a Thing changes, and you're currently achieving this by forwarding all WebSocket message objects relating to that Thing to an array of callback functions registered with a global object on This almost feels like a use case for the Hypothetically if we implemented the I would be open to exploring that as an implementation approach when we transition away from the legacy Web Thing API to the upcoming standardised W3C WoT Thing Protocol. |
Pragmatically though, would you be open to accepting this 'hack', or something that is more palletable to you, in the short term? The reason is that I would like to keep it so that my addons also work on the Webthings Gateway. If my addons start using this "shortcut", and the Gateway doesn't support it, then that would create incompatibility.
About adding it to the window object: one of my thoughts was that it could make more sense to make this faux .. or I could just keep creating Websocket clients for each addon. Would you say the overhead/duplication from paralel clients is not really an issue? It somewhat sounds like you agree that creating a way to |
|
(Another readon why I explored this: the front-end is starting to consume quite a bit of memory if multiple addons with extensions are enabled. In some cases I've started implementing unloading HTML when an addon is navigated away from, for example, in the hopes of recovering some memory). |
|
@flatsiedatsie wrote:
If we were implementing the WoT Scripting API, then no. But we could potentially add Note that the Web Thing Protocol WebSocket Sub-protocol community draft (upon which the WoT Thing Protocol will be based) is a lot more sophisticated than our current Web Thing WebSocket API and involves explicitly observing and unobserving properties rather than just being notified about all property changes on a Thing by default, and the WoT Scripting API is a natural fit on top of that.
If you want a shorter term solution then our current equivalent of The Web Thing API (REST & WebSockets) is currently the most stable API between the front end and back end, but if you want a client-side JavaScript API then ThingModel is how the gateway current abstracts that API on the client-side. It's intended as an internal API rather than for extensions to Consume, but using that is probably better than a hack which forwards WebSocket messages around the front end.
This is currently the intended way to do it, because that's the stable API between the client and server. WebSocket connections are surprisingly lightweight, with each connection only consuming about 10-50KB of RAM so unless you're planning on creating more than about 100,000 connections to a Raspberry Pi all sending data at the same time I wouldn't worry about it.
Yes, I think that's a good idea, and it kind of already exists it's just currently intended as an internal API rather than a stable API for extensions to consume. Implementing the WoT Scripting API could potentially be a way to formalise/stabilise that API in order to prevent breaking add-ons whenever we change the ThingModel.
FWIW I doubt that the memory consumption issues are cause by lots of open WebSocket connections, it's more likely to be caused by memory leaks. It's not something I've paid a lot of attention to recently to be honest, but browser developer tools could help identify the cause. -- In the short term I would recommend that your extensions either open WebSocket connections or try to use |
|
I'm going to close this PR because I don't think this particular solution is quite the right approach, but let me know how you get on if you try to use |
This is probably not how you would implement this, but I thought I'd share as a conversation starter.
This little experiment has been incredibly useful as a light-weight method for addons to subscribe to things. It avoids addons having to create a new websocket client to get things data that is already being received in the browser window.
The Photo Frame addon uses this to get event updates. Now users can use their phone as a remote control for the Photo Frame.
I don't know if this breaks a security model. I figured that any addon can already read the key from window.API. And if the addon is loaded, that means the user is logged in.
As someone who builds a lot of addons I love this. It replaces so much code and complexity around websocket management.