rgraciano / echo-sonos

Amazon Echo integration with Sonos
Other
712 stars 234 forks source link

Node SQS Listener #15

Closed adavep closed 7 years ago

adavep commented 8 years ago

Have you considered leveraging SQS to remove the need for DynDNS and Firewall hole? This may be easier for people to secure, and AWS allows 1 Million SQS messages/mo for free.

A possible solution might be - a NodeJS SQS listener on the server/pi. When an event occurs, Lambda posts to the SNS queue. The listener pulls the message and calls the API locally.

rgraciano commented 8 years ago

I haven't worked with SQS, but I'm assuming that it's low latency and that the listener can keep some kind of persistent connection to the SQS endpoint (also reducing latency). If those two things are true, then you could build an SQS listener feature into node-sonos-http-api itself. That'd be ideal, rather than building another service only as a relay.

jishi commented 8 years ago

Chiming in on this. This could make a lot of sense, but I think amazon SQS might not work as one expects. It seems to be polling based, which might not make sense for low latency messages. Another option would be to use the free plan from https://www.cloudamqp.com/plans.html. RabbitMQ uses persistent connections and are low-latency messages, but is designed to use a persistent connection for publishing messages as well, which doesn't make sense when using the lambda service. However, it has a limited http api which is designed for management, but might make sense for low volume publishing without the requirement for a persistent connection: https://raw.githack.com/rabbitmq/rabbitmq-management/rabbitmq_v3_6_1/priv/www/api/index.html

But thinking about it, a queue system might not be what one wants in this case. If the message can't be delivered directly, you don't want it to stack up, so a pub/sub broker might make more sense. The same company that provides cloudamqp also services https://www.cloudmqtt.com/plans.html which has a free plan as well.

jhmartin commented 8 years ago

A node on SQS: While it is true that it is poll-based, it has a 'long-poll' mode where each 'poll' lasts 20 seconds, and messages are delivered immediately.

As an example, I have a skill to talk to my ZWave devices. I speak the command, and aside from the lambda wake-up delay (as it is a very low velocity function) the command goes from Lambda to SQS to my local listener (ruby, in this case) in about 3 seconds.

jishi commented 8 years ago

I have another suggestion:

ThingMQ has a free, publicly available MQTT broker that has both MQTT, WebSockets and REST support. This means that you can publish a message using REST (which is probably useful for lambda functions), and subscribe to them using MQTT socket.

This means that a local service can subscribe to ThingMQ and listen for messages on a predefined topic (with some unique reference), and a local node service could listen for messages, that either is processed internally or forwarded to my http-api.

Since the free service doesn't have authentication nor protected topics, one should implement some sort of security feature to disallow control unless you are trusted to do so. One simple approach would be to create a hash based on the action using a secret key that your lambda function and your local service are aware of.

This requires no setup of queue/message broker, requires no port forwarding, no SSL nor auth. You can still run encrypted both between broker and local service, as well as REST over HTTPS. The broker would still have access to the messages, and the content, but wouldn't be able to send actions unless it can create a correct hash.

It could also be built super-generic, like sending actual http actions that are just forwarded to localhost, to support any future actions without having to modify the service.

rgraciano commented 7 years ago

Closing, as SQS has since been implemented by a contributor. @jishi's suggestion sounds like a good idea, though. More issues with timeouts might lead us down that path