圆点 飞速的未来即将来到你所在城市举办的一场活动。

加入我们参与 Redis 发布会

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

当在 web 应用程序中导航时,接收实时通知非常常见。通知可能来自聊天机器人、警报系统,或由应用程序推送给一个或多个用户引发的事件。无论通知来源如何,开发人员越来越多地使用 Redis 来创建通知服务。

在由微服务架构支持的现代应用程序中,Redis 通常用作简单缓存和主数据库。但它还可以用作服务之间的通信层,使用由Redis Streams支持的持久消息传递层,这是一个使用其著名的发布/订阅命令的轻量级事件系统。

在本博客文章中,我们将向您展示如何使用 Redis 发布/订阅来创建小型通知服务,以便向 web 应用程序发送消息,该应用程序是使用Vue.jsNode.js和 WebSocket 开发的。

以下是通知的工作原理。如需获得更高分辨率的版本,请点击此 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://#: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 开发服务器,该服务器提供页面服务,并且在你更改页面时自动重新加载页面。

打开浏览器并访问 https://#: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 打印 message 变量的内容,您将在下一代码块中定义该变量。

<script> 中,用以下内容替换掉原内容

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

export default {
  name: 'App',
  data() {
    return {
      message: "",
    }
  },
  created(){
    try {
      const ws = new WebSocket("ws://#: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 channel。例如,如果您使用 Docker 启动 Redis,可使用以下命令连接到它并开始发布消息

> docker exec -it redis-server redis-cli

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

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

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

如您所见,实时将内容推送到网页前端非常容易,只需使用 WebSocket 即可。那么现在让我们改进设计并利用 Bootstrap 添加更加用户友好的界面。

利用 Bootstrap 创建一个 alert 代码块

在本部分,我们将展示如何使用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);

这四行代码导入和注册了 Vue 应用程序中的 Bootstrap 组件。

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://#: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 Insight 或 Redis-cli,并将新消息发送到app:notifications频道。

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

正如您所见,使用 Redis 为您的应用程序创建强大的通知服务非常容易。此示例非常简单,它使用单个频道和服务器并向所有客户端广播。

我们的目标是真正为 WebSocket 和 Redis 发布/订阅提供一种简单的方法,以便将消息从 Redis 推送到 Web 应用程序。使用各种频道向特定客户端传递消息以及扩展和保护应用程序有很多选择。

您还可以在其他方向使用 WebSocket 服务器,消费消息以及向客户端推消息。不过,这是另一篇博文的话题。事实上,敬请期待更多有关如何使用Redis Gears直接在 Redis 数据库中轻松捕获事件并向各种客户端推送某些事件的博文。

更多信息,请参阅以下资源