Serverless 框架实现消息推送

随着云计算的快速发展,Serverless 技术成为了目前最火热的技术之一。Serverless 可以说是一种范式,其不仅仅是一种技术,更是一种架构设计思想。其本质是一种无服务器的云计算模式,强调开发者聚焦于业务逻辑,而不是服务器的管理维护。借助 Serverless 技术,我们可以将服务的开发与运维交给云服务商去完成。本文将介绍如何使用 Serverless 框架实现消息推送功能。

消息推送功能简介

我们都知道,消息推送是一个非常常见的功能,可以用于各种场景,比如社交、电商、团购等。其基本流程是,当用户有新的消息需要推送时,服务端根据用户的订阅信息将消息推送至用户对应的客户端。在实现该功能时,主要涉及到以下两个问题:

  1. 用户的订阅信息如何存储,以及如何实现订阅与取消订阅的操作;
  2. 在消息推送时,如何精准地将消息推送至对应的客户端。

下面,我们将介绍如何使用 Serverless 框架实现消息推送,并解决上述两个问题。

Serverless 框架简介

Serverless 框架是基于云函数服务的一种框架,其可以轻松地部署和管理云函数,并提供了丰富的环境和工具。Serverless 框架支持多种云服务商,包括 AWS、Azure、Google Cloud 等。此外,Serverless 框架还提供了许多插件和模板,可以帮助开发者更快速地实现各种功能。如果您还不了解 Serverless 框架,可以参考 Serverless Framework 官方文档

实现步骤

1. 创建云函数

首先,我们需要使用 Serverless 框架创建一个云函数,用于实现消息推送功能。在终端中执行以下命令:

上述命令将创建一个名为 push-service 的项目,并且使用 aws-nodejs 模板。该模板会生成如下文件:

其中,handler.js 是云函数的实现代码,serverless.yml 是 Serverless 框架的配置文件。

2. 安装依赖

push-service 目录下执行以下命令,安装依赖:

  • serverless-offline 插件用于在本地模拟云函数运行环境;
  • serverless-webpack 插件用于将 TypeScript 代码编译成云函数支持的 JavaScript 代码;
  • serverless-plugin-warmup 插件用于提前预热云函数,缩短第一次请求的响应时间;
  • expressbody-parser 库用于实现 Web 服务,方便测试云函数;
  • uuid 库用于生成唯一标识符,用于标识用户。

3. 实现订阅和取消订阅的接口

我们需要实现以下两个接口:

  1. /subscribe:用于订阅消息推送服务;
  2. /unsubscribe:用于取消订阅消息推送服务。

接口的实现代码如下:

import * as express from "express";
import {v4 as uuidv4} from "uuid";
import {Item, SubscriptionRequest} from "./interfaces";

const app = express();
app.use(express.json());

let subscriptionList: Item[] = [];

app.post("/subscribe", (req, res) => {
    const {url} = req.body as SubscriptionRequest;

    if (!url) {
        return res.status(400).json({message: "The 'url' parameter is required."});
    }

    const hasSubscription = subscriptionList.some(item => item.url === url);
    if (hasSubscription) {
        return res.status(409).json({message: "This url is already subscribed."});
    }

    const id = uuidv4();
    const item = {id, url};
    subscriptionList.push(item);
    res.json({message: `Subscription created. Id: ${id}`});
});

app.delete("/unsubscribe/:id", (req, res) => {
    const {id} = req.params;
    const index = subscriptionList.findIndex(item => item.id === id);

    if (index === -1) {
        return res.status(404).json({message: `Subscription with id '${id}' not found.`});
    }

    subscriptionList.splice(index, 1);
    res.json({message: `Subscription with id '${id}' has been unsubscribed.`});
});

export const handler = app;

以上代码中,我们定义了 subscriptionList 数组用于存储订阅信息。订阅信息中包括 id 和 url 两个参数,其中 id 为唯一标识符,用于标识用户。订阅消息推送服务时,需要传递 url 参数。取消订阅时,需要提供订阅的 id。

4. 实现消息推送功能

我们需要实现在消息推送时,根据用户的订阅信息将消息推送至对应的客户端。具体实现方法如下:

import * as express from "express";
import * as http from "http";
import {v4 as uuidv4} from "uuid";
import {Item} from "./interfaces";

const app = express();

let subscriptionList: Item[] = [];

app.post("/subscribe", (req, res) => {
    // 省略
});

app.delete("/unsubscribe/:id", (req, res) => {
    // 省略
});

app.post("/push", async (req, res) => {
    const {message} = req.body;
    if (!message) {
        return res.status(400).json({message: "The 'message' parameter is required."});
    }

    try {
        const responses = await Promise.all(subscriptionList.map(async ({url}) => {
            const id = uuidv4();
            const postOptions = {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    "X-Request-Id": id
                },
                body: JSON.stringify({message})
            };

            const response = await http.request(url, postOptions);
            return {url, id, statusCode: response.statusCode};
        }));

        return res.json(responses);
    } catch (e) {
        console.error(e);
        return res.status(500).json({message: "Unexpected error occurred."});
    }
});

export const handler = app;

以上代码中,我们定义了 /push 接口,当有新消息需要推送时,可以向这个接口发送 POST 请求,参数为 message。在实现时,我们通过 Promise.all 发送多个并发请求,将消息推送至用户的客户端。其中,我们使用了 http 库,用于发送请求。

在发送消息时,我们需要为每个请求生成一个唯一的 requestId,并附加在 HTTP 头部。客户端可以根据此 requestId 进行去重处理,并防止重复推送。

部署云函数

接下来,我们需要通过 Serverless 框架部署云函数。在 push-service 目录下执行以下命令:

如果您的 AWS 账号没有足够的权限进行部署,请参考 Serverless Framework 官方文档 开启相应权限。

部署完成后,可以查看云函数的 URL,并在本地测试消息推送功能。在终端中执行以下命令:

在收到推送消息后,可以通过浏览器打开 http://localhost:3000,查看推送的消息。

总结

本文介绍了如何使用 Serverless 框架实现消息推送功能。通过 Serverless 框架,我们可以快速开发和部署云函数,同时享受到云服务商提供的高可用、高性能等优秀特性。如果您还没有尝试过 Serverless 技术,可以试着使用该技术实现一些小功能,领略其魅力。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a88730add4f0e0ff1a995a


纠错反馈