Is it possible to use Socket.io with AWS Lambda?

Is it possible to build a function in AWS Lambda that creates a websocket and send data to subscribed applications?

Something like this:

John has the app SuperPhotoApp opened in his phone but decides to use the desktop browser to upload a photo to the SuperPhotoApp service (a S3 Bucket), this event executes a Lambda function that creates a socket.io server and pushes the update to all subscribers, his phone had the app opened so the app automatically updates with the new photo.

This is something that can be done with push notifications or Amazon SNS, but what if I need real-time behaviour for example an online game where I need to update the position of a character.

If this is not possible with Lambda, is there any solution where I can update my opened app using a desktop browser?

Amazon EC2 is the only option? I've read that it has problems with scaling, that's why I'm commenting on Lambda.

58429 次浏览

I don't think that Lambda is going to work for the case you described here. The link to the AWS forum below points out that the Lambda function can only run for a maximum of 15 minutes and further since you are charged per 100ms of function runtime this would probably be cost-prohibitive. There is a comment from Amazon saying they've heard the request several times so are interested in some way to allow for this.

https://forums.aws.amazon.com/thread.jspa?threadID=205761

Here is a post from someone who appears to have a good deal of success using EC2 and NodeJS but he had to use an alternative to Socket.io called Websockets/ws.

http://www.jayway.com/2015/04/13/600k-concurrent-websocket-connections-on-aws-using-node-js/

If you plan to run your server behind a load balancer it looks like you are going to have a few more hoops to jump through:

https://web.archive.org/web/20160118124227/http://coding-ceo.ghost.io/how-to-run-socket-io-behind-elb-on-aws

Recently AWS released support of WebSockets for IoT service. It is very easy to use as Pub/Sub message system for serverless web applications. You can post new messages from AWS lambda function via http post request and receive them as websocket messages on a client.

I wrote a small npm package that handles websocket connection to MQTT server from the front-end app. Check out aws-mqtt-client

No! Lambda was not designed for socket.io. Lambda was designed for short-time processing only.

EDIT: API Gateway supports WebSockets now.

--
Old answer:

If you want to provide cheap notifications, you can try external services like PubNub or Realtime Framework.

If you want to stay using only Amazon services, don't bother trying SNS because it won't serve for this use case (there isn't an endpoint for browsers).

However, you can try AWS IoT. I know that it sounds strange, but since it supports browsers through MQTT, it's a great tool for cheap, fast and easy to develop notifications. Follow this link for a great tutorial. Demo code is available here.

I think you can combine AWS Lambda with other PUB/SUB service like PUBNUB https://www.pubnub.com/docs/pubnub-rest-api-documentation.

  1. front-end/app use AWS Lambda to dynamically create and manage topics
  2. front-end/app get topic info from AWS Lambda or DB
  3. front-end/app join corresponding topics and send message to PUBNUB directly

Update (since AWS re:invent 2018): API Gateway now supports websockets! See examples that use API Gateway websockets with Lambda here:

and documentation for this feature of API Gateway here: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api.html

There's also an interesting example of a Node.js framework that uses socket.io with API Gateway, but I haven't investigated if it specifically will work for your use case: https://github.com/tiaod/moleculer-io


You should consider using Amazon IoT Core. I'll explain.

If you have a real-time situation where you need to perform a computation or leverage analytics on a real-time stream, you need to be thinking about streaming events (that reflect the state changes in real-time) to a platform designed for fast, high-availability event-streaming, such as a Kafka implementation like AWS Kinesis. Then you can consume the event-stream from a tool designed for real-time streaming analytics, such as Kinesis Analytics or Apache Spark or Apache Storm.

Then you can consume the streaming analytics (and optionally also additional event-provided data) using AWS Lambda (which can be triggered by events that come through your Kinesis pipeline) to push updates to all of the subscribers. You can push updates in real-time to these subscribers if wired up through the Amazon IoT Core service specifically if you create a "topic" for each user. The service is designed so that you don't have an upper limit on the number of topics you can have, so it should scale elastically.

This is an example of a best-practice "big-data" serverless (as long as you avoid maintaining VMs and only use serverless/managed services) approach to your problem, and it will be much more elastic, cost-effective, easy to maintain, and scalable than managing your own EC2 instances and needing to worry about all of the additional headaches with load-balancing and availability and replication and server-state and idempotency and scaling and wasted resources and the deployment pipeline and instance monitoring, etc., etc..

You can even push events directly to the client browser with web sockets over MQTT (which is very fast and lightweight) if you use the Amazon IoT Core service, and you can integrate it directly with AWS Lambda. There's a great demo app that uses IoT Core here: https://github.com/aws-samples/aws-iot-chat-example

Personally, I prefer the approach that is less expensive, easier to maintain, performs better, allows me to get sleep at night, and allows me to get uninterrupted sleep that is free of nightmares.

If you're looking for real-time functionality I would turn toward Firebase Real Time Database or Firestore. I use both quite heavily and I have to say they're amazing. Check it out here https://firebase.google.com

Yes, you can publish events as a socket.io client to a socket.io server using AWS Lambda.

Steps to implement:

  • Create a node app locally, and execute npm install socket.io-client --save in the project folder.
  • Implement the handler code in index.js. Here is an example:
exports.handler = async (event) => {
var io = require('socket.io-client');
var socket = io.connect("http://example.com:9999");
let payload = { "id": "1" };
socket.emit("MyEvent", payload);
return 'Sent message!';
};
  • Create a zip file of the folder.
  • In AWS Lambda, Select Upload a .Zip file
  • Ensure that after the files are uploaded that the file structure looks similar to:

Project

  • node_modules
  • index.json
  • package-lock.json
  • package.json

Save and test.

You can't use Lambda to host a socketio server. But you can use lambda to emit events into an external socketio server