dot Redis 8 来了—而且是开源的

了解更多

如何使用 Redis、Websockets 和 Vue.js 创建通知服务

在 Web 应用程序中导航时,获取实时通知非常常见。 通知可能来自聊天机器人、警报系统,或者由应用程序推送给一个或多个用户的事件触发。 无论通知的来源是什么,开发人员都在越来越多地使用 Redis 来创建通知服务。

在由微服务架构驱动的现代应用程序中,Redis 通常用作简单的缓存和主数据库。 但它也用作服务之间的通信层,使用持久的消息传递层,该层由Redis Streams提供支持,它是一个轻量级的事件系统,使用其众所周知的Pub/Sub(发布/订阅)命令。

在这篇博文中,我们将向您展示使用 Redis Pub/Sub 向 Web 应用程序发送消息是多么容易,该 Web 应用程序使用 Vue.jsNode.js 和 WebSockets 开发。

以下是通知的工作方式。 要获得更高分辨率的版本,请点击此 gif 以查看视频。

先决条件

此演示服务使用

启动 Redis 服务器

如果您还没有运行 Redis 实例,可以使用 Docker 启动它; 在终端中,运行此命令

> docker run -it --rm --name redis-server -p 6379:6379 redis

Redis 现在应该已启动并运行,并准备好接受连接。

使用 Node.js 创建 WebSocket 服务器

要使用正确的结构配置项目,请打开终端并输入以下命令

> mkdir notifications

> cd notifications

> mkdir notif-server

> cd notif-server

使用 npm 创建一个新的 Node.js 项目(-y 参数会将所有值设置为默认值)

> npm init -y

> npm install ws redis

上面的最后一个命令将 WebSocketRedis 依赖项添加到您的项目中。 您现在可以编写一些代码了!

编写 WebSocket 服务器

打开您喜欢的 Node.js 代码编辑器(我使用 Visual Studio Code),只需输入代码 “code .” 即可打开当前目录。 在您的编辑器中,创建一个名为 server.js 的新文件。

const WebSocket = require('ws');
const redis = require('redis');

// Configuration: adapt to your environment
const REDIS_SERVER = "redis://localhost:6379";
const WEB_SOCKET_PORT = 3000;

// Connect to Redis and subscribe to "app:notifications" channel
var redisClient = redis.createClient(REDIS_SERVER);
redisClient.subscribe('app:notifications');

// Create & Start the WebSocket server
const server = new WebSocket.Server({ port : WEB_SOCKET_PORT });

// Register event for client connection
server.on('connection', function connection(ws) {

  // broadcast on web socket when receving a Redis PUB/SUB Event
  redisClient.on('message', function(channel, message){
    console.log(message);
    ws.send(message);
  })

});

这个简单的 Node.js 程序仅限于演示,侧重于

  • 连接到 Redis(第 9 行)
  • 订阅来自 “app:notifications” 频道的消息(第 10 行)
  • 启动 WebSocket 服务器(第 13 行)
  • 注册用户客户端连接(第 16 行)
  • 监听 Redis 订阅事件(第 19 行)
  • 并将消息发送到所有 WebSocket 客户端(21)。

第 5 行和第 6 行仅用于配置 Redis 服务器位置和 Web Socket 服务器使用的端口。 正如您所看到的,它非常简单。

运行 WebSocket 服务器

如果您尚未安装 nodemon,请立即安装。 然后使用以下命令启动 WebSocket 服务器

> nodemon server.js

现在让我们创建前端,它将接收通知并将其打印给用户。

使用 Vue.js 创建前端

打开一个新的终端,然后从 notifications 目录运行以下命令

如果您尚未安装 Vue CLI 工具,请立即使用命令 npm install -g @vue/cli 进行安装。

> vue create webclient

> cd web-client

此命令创建一个新的 Vue 项目,该项目已准备好执行和扩展。

此演示要安装的最后一个软件包是 BootstrapVue,它使您可以轻松使用来自流行的 Bootstrap 框架的 CSS 库和组件。

> npm install bootstrap-vue bootstrap

在您喜欢的代码编辑器中打开 web-client 目录,然后启动新创建的 Vue 应用程序

> npm run serve

最后一个命令启动 Vue 开发服务器,该服务器将提供页面,并在您更改页面时自动重新加载页面。

打开您的浏览器,然后转到 http://localhost:8080;您应该在其中看到默认的 Vue 欢迎页面

将 WebSocket 添加到前端

Vue 框架非常简单,对于这篇文章,我们将使代码尽可能简单。 因此,让我们快速了解目录结构

├── README.md
├── babel.config.js
├── node_modules
├── package-lock.json
├── package.json
├── public
│   ├── favicon.ico
│   └── index.html
└── src
    ├── App.vue
    ├── assets
    │   └── logo.png
    ├── components
    │   └── HelloWorld.vue
    └── main.js

根级别的文件(babel.config.jspackage.jsonpackage-lock.jsonnode_modules)用于配置项目。 最有趣的部分(至少现在)位于 src 目录中

  • main.js 文件是应用程序的主要 JavaScript 文件,它将加载所有公共元素并调用 App.vue 主屏幕。 我们稍后将修改它以添加 Bootstrap 支持。
  • App.vue 是一个文件,其中包含特定页面或模板的 HTML、CSS 和 JavaScript。 作为应用程序的入口点,默认情况下所有屏幕都共享此部分,因此它是在此文件中编写通知客户端部分的好地方。

public/index.html 是加载 DOM 的静态入口点。 如果您查看它,您将看到一个 <div id=”app”>,用于加载 Vue 应用程序。

此演示非常简单,您只需要修改两个文件:App.vuemain.js 文件。 在实际应用程序中,您可能会创建一个 Vue.js 组件,该组件可以在各个位置重复使用。

更新 App.vue 文件以显示 WebSocket 消息

在您的编辑器中打开 App.vue 文件,并添加下面列出的信息。 在页面底部,正好在 </div> 标记之前,添加以下 HTML 块

<hr/>
<h3>
  {{message}}
</h3>
<hr/>

使用 {{message}} 表示法,您指示 Vue 打印消息变量的内容,您将在下一个块中定义该变量。

<script> 中,将内容替换为

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  data() {
    return {
      message: "",
    }
  },
  created(){
    try {
      const ws = new WebSocket("ws://localhost:3000/");
      ws.onmessage = ({data}) => {
        this.message =  data;
        console.log(this.message);
      }
    } catch(err) {
      console.log(err);
    }
  },
  components: {
    HelloWorld
  }
}
</script>

这几行代码用于

  • 连接到 WebSocket 服务器(第 13 行)
  • 使用来自服务器的消息并将它们发送到本地 message 变量(第 13-17 行)

如果您仔细查看所做的更改,您可以看到您已添加

  • 一个 data() 函数,它向 Vue 组件指示您正在定义可以绑定到屏幕本身的局部变量(第 6-10 行)
  • 一个 created() 函数,该函数在初始化时由 Vue 组件自动调用

将消息从 Redis 发送到您的 Vue 应用程序

现在应该运行 WebSocket 服务器和 Vue 前端,并且由于您添加的几行 JavaScript 而连接。 是时候测试它了!

使用 Redis CLI 或 RedisInsight,将一些消息发布到 app:notifications 频道。 例如,如果您使用 Docker 启动了 Redis,则可以使用以下命令连接到它并开始发布消息

> docker exec -it redis-server redis-cli

127.0.0.1:6379> PUBLISH app:notifications  "message from Redis2"

您应该在浏览器中的应用程序底部看到该消息出现

在视图应用程序中显示的 Redis 消息。

正如您所看到的,使用 WebSocket 实时将内容推送到您的 Web 前端非常容易。 因此,现在让我们改进设计,并使用 Bootstrap 添加一个更加用户友好的界面。

使用 Bootstrap 创建警报块

在本节中,我们将向您展示如何使用 Bootstrap 警报组件,该组件在新消息收到时出现,并在几秒钟后使用简单的倒计时自动消失。

Main.js 文件

打开 main.js 文件,并在上次导入后添加以下行

import { BootstrapVue } from 'bootstrap-vue';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue/dist/bootstrap-vue.css';

Vue.use(BootstrapVue);

这四行代码将 Bootstrap 组件导入并注册到您的 Vue 应用程序中。

App.js 文件

App.vue 文件中,将您之前添加的代码(两个 <hr/> 标记之间的所有内容以及标记本身)替换为以下代码

<div class="d-inline-flex p-4">
   <b-alert id="notification" 
      :show="dismissCountDown"
      dismissible
      @dismissed="dismissCountDown=0"
      @dismiss-count-down="countDownChanged"
    >
    New notification: {{message}}
   </b-alert>
</div>

此组件使用多个属性

  • id=”notification” 是用于在 JavaScript 或 CSS 代码中引用该元素的元素 ID。:show=”dismissCountDown” 表示仅当 dismissCountDown 变量不为 null 且不为 0 时,该组件才可见。
  • dismissible 在警报中添加一个小图标,让用户可以手动关闭它。
  • @dismissed=”dismissCountDown=0″ 表示警报框将在 dismissCountDown 等于 0 时关闭。
  • @dismiss-count-down=”countDownChanged” 是倒计时方法。

让我们添加几行 JavaScript 代码来定义警报组件使用的变量和方法。

data() {
    return {
      message: "",
      dismissSecs: 5,
      dismissCountDown: 0,      
    }
  },
  created(){
    try {
      const ws = new WebSocket("ws://localhost:3000/");
      ws.onmessage = ({data}) => {
        this.message =  data;
        this.showAlert();
      }
    } catch(err) {
      console.log(err);
    }
  },
  methods: {
    countDownChanged(dismissCountDown) {
      this.dismissCountDown = dismissCountDown
    },
    showAlert() {
      this.dismissCountDown = this.dismissSecs
    }
  },

...

在本节中,您已经

  • dismissSecsdismissCountDown 变量添加到 data() 方法(第 4-5 行),用于控制计时器,该计时器在再次隐藏警报之前显示警报。
  • 创建了显示和隐藏警报组件的方法(第 10-26 行)。
  • 当收到新消息时,调用 showAlert() 方法(第 13 行)。

让我们试一下!

返回到 redis-cli 或 Redis Insight,并将新消息发布到 app:notifications 频道。

警报框中的通知在 Vue 应用程序中可见。

正如您所看到的,使用 Redis 可以轻松地为您的应用程序创建一个强大的通知服务。 这个例子非常基础,使用单个通道和服务器,并广播给所有客户端。

目标真的是提供一种简单的方法,从 WebSocket 和 Redis Pub/Sub 开始,将消息从 Redis 推送到 Web 应用程序。 有许多选项可以使用各种渠道将消息传递给特定客户端,并扩展和保护应用程序。 

您也可以在另一个方向使用 WebSocket 服务器,以消费消息以及将消息推送到客户端。 但这是另一篇博文的一个大话题。 事实上,请继续关注更多关于如何使用 Redis Gears 直接在 Redis 数据库中轻松捕获事件并将一些事件推送到各种客户端的博文。

有关更多信息,请参见以下资源