是否可以将 Socket.io 与 AWS Lambda 一起使用?

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

是否可以在 AWS Lambda 中构建一个函数来创建 websocket 并将数据发送到订阅的应用程序?

像这样:

John 在他的 phone 中打开了应用程序 SuperPhotoApp,但决定使用桌面浏览器将照片上传到 SuperPhotoApp 服务(S3 存储桶),此事件执行创建 socket.io 服务器并将更新推送给所有订阅者,他的 phone 打开了应用程序,因此应用程序会自动更新新照片。

这可以通过推送通知或 Amazon SNS 完成,但是如果我需要实时行为,例如需要更新角色位置的在线游戏,该怎么办。

如果 Lambda 无法做到这一点,是否有任何解决方案可以让我使用桌面浏览器更新我打开的应用程序?

Amazon EC2 是唯一的选择?我读到它在缩放方面存在问题,这就是我评论 Lambda 的原因。

我认为 Lambda 不适用于您在此处描述的情况。下面 AWS 论坛的 link 指出 Lambda 函数只能 运行 最多 15 分钟,而且因为你每 100 毫秒函数 运行 时间收费,这可能是成本过高。亚马逊的评论说他们已经多次听到这个请求,所以有兴趣以某种方式允许这个。

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

这是一个 post 的人,他似乎使用 EC2 和 NodeJS 取得了很大的成功,但他不得不使用 Socket.io 的替代方法 Websockets/ws。

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

如果您打算 运行 您的服务器在负载均衡器后面,看起来您将有更多的障碍需要跳过:

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

最近AWS released support of WebSockets for IoT服务。它非常易于用作无服务器 Web 应用程序的 Pub/Sub 消息系统。您可以通过 http post request post 来自 AWS lambda function 的新消息,并在客户端上以 websocket 消息的形式接收它们。

我写了一个小的 npm 包来处理从前端应用程序到 MQTT 服务器的 websocket 连接。查看 aws-mqtt-client

不! Lambda 不是 为 socket.io 设计的。 Lambda 专为短时处理而设计。

编辑:API 网关现在支持 WebSockets

--
旧答案:

如果你想提供便宜的通知,你可以尝试像PubNub or Realtime Framework这样的外部服务。

如果您只想继续使用 Amazon 服务,请不要费心尝试 SNS,因为它不适用于此用例(没有浏览器端点)。

不过,你可以试试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

我认为您可以将 AWS Lambda 与其他 PUB/SUB 服务结合使用,例如 PUBNUB https://www.pubnub.com/docs/pubnub-rest-api-documentation

  1. front-end/app 使用 AWS Lambda 动态创建和管理主题
  2. front-end/app 从 AWS Lambda 或 DB 获取主题信息
  3. front-end/app加入相应话题直接发消息到PUBNUB

更新(自 AWS re:invent 2018 年起):API 网关现在支持 websockets!在此处查看将 API 网关 websockets 与 Lambda 结合使用的示例:

API 网关此功能的相关文档位于此处:https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api.html

还有一个 Node.js 框架的有趣示例,它使用 socket.io 和 API 网关,但我没有调查它是否特别适用于您的用例:https://github.com/tiaod/moleculer-io


您应该考虑使用 Amazon IoT Core。我会解释。

如果您遇到需要在实时流上执行计算或利用分析的实时情况,则需要考虑流式事件(实时反映状态变化)以专为快速、高可用性事件流设计的平台,例如 AWS Kinesis 等 Kafka 实现。然后,您可以使用专为实时流分析设计的工具中的事件流,例如 Kinesis Analytics 或 Apache Spark 或 Apache Storm。

然后您可以使用 AWS Lambda(可以由通过您的 Kinesis 管道的事件触发)使用流分析(以及可选的其他事件提供的数据)以将更新推送给所有订阅者。如果通过 Amazon IoT Core 服务连接,您可以将更新实时推送给这些订阅者,特别是如果您为每个用户创建 "topic"。该服务的设计使您可以拥有的主题数量没有上限,因此它应该可以弹性扩展。

这是解决您的问题的最佳实践 "big-data" 无服务器(只要您避免维护 VM 并且只使用 serverless/managed 服务)方法的示例,它会更有弹性,比管理您自己的 EC2 实例更具成本效益、易于维护和可扩展,并且需要担心负载平衡、可用性和复制、服务器状态、幂等性和扩展以及浪费的资源和部署管道等所有额外的麻烦和实例监控等等。

如果您使用 Amazon IoT Core 服务,您甚至可以通过 MQTT(非常快速和轻量级)使用 Web 套接字将事件直接推送到客户端浏览器,并且可以将其直接与 AWS Lambda 集成。 这里有一个使用 IoT Core 的很棒的演示应用程序:https://github.com/aws-samples/aws-iot-chat-example

就我个人而言,我更喜欢更便宜、更易于维护、性能更好、让我晚上能入睡并让我获得 不间断 睡眠的方法没有噩梦。

如果您正在寻找实时功能,我会转向 Firebase 实时数据库或 Firestore。我都大量使用它们,我不得不说它们很棒。在这里查看 https://firebase.google.com

是的,您可以使用 AWS Lambda 将事件作为 socket.io 客户端发布到 socket.io 服务器。

实施步骤:

  • 在本地创建一个node app,在项目文件夹下执行npm install socket.io-client --save
  • 实现index.js中的处理程序代码。这是一个例子:
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!';
};
  • 创建文件夹的 zip 文件。
  • 在 AWS Lambda 中,Select上传 .Zip 文件
  • 确保文件上传后文件结构类似于:

项目

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

保存并测试。

您不能使用 Lambda 来托管 socketio 服务器。但是您可以使用 lambda 将事件发送到外部 socketio 服务器