发布于 2026-01-06 0 阅读
0

实时事件和流数据入门(JS) feathers-chat-vuex Feathers Chat

实时事件和流数据入门(JS)

羽毛聊天 Vuex

羽毛聊天

关于本系列

在本系列教程中,我将探讨如何使用 JavaScript 开发事件驱动型 Web 应用程序。我们将使用 Vue 作为前端框架,FeathersJS 作为后端框架来实现这一目标。如果您对开发实时和流数据应用程序感兴趣,请关注本系列教程。教程内容将涵盖聊天应用程序、流媒体视频或音频应用程序、设备驱动型应用程序(例如物联网领域的应用程序)等诸多方面。

本系列文章假定读者已熟悉 JavaScript,并了解 Vue 和 Node.js 的基本概念,例如如何在 Vue/Node 中搭建一个简单的项目。我会尽力讲解更复杂的概念。如有任何不清楚的地方,请留言,以便我更新文章使其更加清晰易懂。

什么是实时数据和流数据?

实时数据是指收集后立即提供的数据。随着硬件和计算能力的不断提升,企业利用实时数据分析来识别潜在问题或机遇已变得越来越普遍。收集到的数据可以“即时”转换并立即呈现给决策者。

传统上,这种情况常见于设备和地理信息系统 (GIS),它们会频繁地发出传感器和/或位置数据。

随着人工智能和数据仓库技术的日益普及,实时处理数据已成为相当普遍的现象。对于高容量应用而言,能够随着系统状态的变化实时更新网站变得越来越重要。

实时事件和数据场景

实时数据的应用只会随着时间的推移而不断增加。以下是一些常见的应用场景:

健康与健身设备

随着科技的不断进步,能够提供即时反馈的设备将会越来越多,以优化医生提供的医疗服务。配备众多传感器的医疗设备通常需要即时传输信息,以便医生和患者能够获得做出明智决策所需的信息。过去,X光片的处理和显影需要数天时间,而现在只需几分钟即可完成。其他类似的诊断程序也日益普及,能够为医生提供近乎实时的反馈,帮助他们更好地评估患者的病情。

同样,健身追踪器可以传输心率等数据,并记录您运动或睡眠时的活动。它可以提醒您何时达到每日步数目标,或警告您运动过度。这些设备都依赖实时更新,以便在事件发生时及时通知用户。

电子商务与日程安排

库存管理对提升客户满意度至关重要。库存是有限的,因此当用户购买商品时,该商品通常会从库存中扣除。这在访问量较低的网站上通常运作良好,因为在任何给定时间,单个用户可能只会购买一件商品。但是,当多个用户同时尝试购买同一件商品时会发生什么呢?

只能由一人完成购买。一旦发现产品缺货,其他订单将被取消。如果处理时间超出客户的耐心和预期,可能会导致糟糕的客户体验。

通过实时事件更新,客户可以获知商品已被购买,并在完成购买前将其从购物车中移除。这有助于更好地管理客户预期。同样的方法也适用于预订或日程安排应用程序。

作战意识

有时,实时监控数据对业务运营至关重要。对于任何类型的计算机系统启发式算法或诊断平台而言,这一点通常都适用。例如,在预防和缓解网络攻击时,通常需要跟踪进入网络的流量。

攻击发现得越早,企业就越有可能从攻击中恢复或抵御攻击。在这种情况下,实时更新对于准确反映当前情况至关重要。

处理实时数据

在网站上接收实时更新最常见的方式是通过实时传输协议,例如套接字。套接字与服务器保持开放的通道,允许数据和事件通知通过。

Socket.io是一个流行的用于支持此类连接的库。FeathersJS开箱即用地支持 Socket.io,并提供额外的脚手架功能,用于构建强大的后端以支持实时应用程序

FeathersJS 入门

Feathers 入门非常简单。我会简要介绍如何创建自己的项目,以便您能立即上手使用。之后,我会使用一个预置的项目模板来演示不同的使用场景。您可以创建自己的项目,也可以使用同一个模板进行演示。

Feathers 命令行界面 (CLI)

Feathers 提供了一个命令行界面 (CLI),使您能够快速生成新的应用程序。全局安装 Feathers CLI 即可生成应用程序:

npm install @feathersjs/cli -g

为你的项目创建一个文件夹。

mkdir feathers-realtime
cd feathers-realtime/
feathers generate app
Enter fullscreen mode Exit fullscreen mode

Feathers CLI 会提示您一些问题,以帮助您配置项目,包括身份验证、测试框架和数据源提供程序。您可以根据自己的喜好进行调整。当被问及 API 时,请务必为您的项目选择 socket.io。配置完成后,CLI 将自动生成项目目录结构和文件。

要了解有关生成文件的更多信息,请访问文档

项目模板

为了增加一些功能,我将使用 FeathersJS 社区中现有的项目模板,并在此基础上进行构建。

前端方面,我们将以 feathers-vuex-chat 前端为起点,它利用了feathers-vuex库:

GitHub 标志 feathersjs-ecosystem / feathers-chat-vuex

Feathers Chat 使用 Feathers-Vuex 3.0 构建

羽毛聊天 Vuex

草坪管理员徽章

基于 Feathers-Vuex 3.x 构建

这是使用feathers-vuex的 Feathers Chat 单页应用程序的新版本。还有一个版本已停止维护,地址为https://github.com/feathersjs-ecosystem/feathers-chat-vuex-0.7。它可以作为新旧 API 对比的参考。


Feathers聊天界面

API 设置

本项目旨在与feathers-chat应用程序配合使用。请确保feathers-chat服务器应用程序已运行,然后再尝试使用本项目。

项目设置

yarn install

编译和热重载以进行开发

yarn serve

编译并压缩以供生产环境使用

yarn build

整理和修复文件

yarn lint

自定义配置

参阅配置参考






后端方面,我们将以 feathers-chat 后端为起点:

GitHub 标志 feathersjs / feathers-chat

Feathers 实时聊天应用程序

羽毛聊天

羽毛标志

一个基于 FeathersJS 的聊天应用程序

NPM 版本

复制

关于

该存储库包含来自官方 Feathers 聊天指南的服务器应用程序,以及不同框架的聊天前端示例。

API 服务器

TypeScript

聊天 API 服务器的 TypeScript 版本位于feathers-chat-ts项目中。要启动它,请按如下方式安装依赖项:

cd feathers-chat-ts
npm install

然后编译源代码并运行数据库迁移,这将初始化feathers-chat.sqlite文件中的 SQLite 数据库。

npm run compile
npm run migrate

现在可以开始使用了:

npm start

或者在开发模式下

npm run dev

现在访问http://localhost:3030开始聊天吧🕊️

前端

纯 JavaScript

在api 服务器示例的静态托管的public文件夹中可以找到纯 JavaScript 前端

React

待定

VueJS

待定






本文的合并代码库可以在这里找到:

GitHub 标志 冥想龙/实时羽毛

Javascript 中的实时和流数据入门

羽毛实时

该仓库与一篇关于使用 FeathersJS 开发事件驱动型应用程序的博客文章相对应。




实时传输

如上所述,Feathers 支持 Socket.io 作为实时传输协议。它还支持Primus,Primus 是实时框架的封装器,这使得 Feathers 可以适配企业其他部门使用的现有实时框架。

Hello World - 向前端推送消息

为了启动这个项目,我将在后端模拟一些数据,以演示前端的实时更新。我们将创建一个简单的仪表盘,其中包含不同的图表来显示实时数据。在接下来的系列文章中,我们将深入探讨更多用例。

项目运行

此模板前端使用 Vue。要运行开发服务器,请yarn servefeathers-chat-vuex目录下使用 `<filename>` 命令。默认情况下,服务器将在 8080 端口启动。在浏览器中访问http://localhost:8080/即可查看 Web 应用。

本项目后端使用 FeatherJS。要运行开发服务器,请使用以下命令。默认情况下,服务器将在http://localhost:3030npm run dev启动。

前端应该已经通过/src/feathers-client.js设置配置为通过端口 3030 连接到后端。

嘲讽数据

为了简化这篇博文,我将模拟 Feathers 后端定期发送的数据。我们将使用事件监听器来检测用户何时连接到服务器,并在用户连接后开始数据推送。

在程序中channels.js,每次与服务器建立连接时,它都会开始每 5 秒发送一次数据。这些数据是使用一个辅助函数随机生成的getRandomInt。它提供了一些数据变量,我将使用这些变量来更新图表。

为了更贴近实际应用场景,这些数据可以由服务或其他数据源提供(下文将介绍自定义服务的实现,这是一种更优方案)。例如,可以考虑发送日志,以提供持续不断的日志数据流。或者,您也可以发送二进制数据(例如其他用户生成的音频或视频)来显示给用户。

  let logins = [
    getRandomInt(50, 70),
    getRandomInt(50, 70),
    getRandomInt(50, 70),
    getRandomInt(50, 70),
    getRandomInt(50, 70),
    getRandomInt(50, 70),
    getRandomInt(50, 70),
  ];

  let interval;
  app.on("connection", (connection) => {
    // On a new real-time connection, add it to the anonymous channel
    app.channel("anonymous").join(connection);
    // create 5 second interval to emit "dataAvailable" event with data payload
    interval = setInterval(() => {
      console.log("Sending new data");
    // remove one value, add a new one
      logins.shift();
      logins.push(getRandomInt(50, 70));
    // send the data through the 'dataAvailable' event
      app.io.emit("dataAvailable", {
        messageCount: getRandomInt(1000, 10000) + getRandomInt(0, 100),
        activeChatRooms: getRandomInt(5, 100),
        recentLogins: logins,
        openTickets: getRandomInt(0, 100),
        closedTickets: getRandomInt(0, 100),
        unassignedTickets: getRandomInt(0, 100),
      });
    }, 5000);
  });

  app.on("disconnect", (connection) => {
    clearInterval(interval);
  });
Enter fullscreen mode Exit fullscreen mode

当你运行npm run dev命令启动服务器时,一旦有用户连接,服务器就应该开始传输数据。

前端套接字处理

Feathers 为 socket.io 客户端提供了一个封装,可以与 Feathers 后端无缝协作。Feathers-vuex 集成了这个库,并在 Vuex store 中提供了实时 socket 事件支持。要开始使用,请先将以下库添加到您的项目中(如果您的项目中尚未包含这些库):

yarn add @feathersjs/feathers @feathersjs/socketio-client @feathersjs/authentication-client socket.io-client @vue/composition-api feathers-vuex feathers-hooks-common
Enter fullscreen mode Exit fullscreen mode

这些软件包已添加到项目模板中。@feathersjs/feathers它们提供了连接框架@feathersjs/socketio-client用于通过 socket.io 实时传输与 Feathers 服务器通信。其余库则为前端的 Vue/Vuex 提供支持。@feathersjs/authentication-clientsocket.io-client

默认情况下,该feathers-vuex默认使用实时连接(另一种选择是 REST API 调用,您也可以对其进行配置)。

如果您是第一次使用Feathers-Vuex,我建议您先阅读文档,其中详细介绍了设置过程和关键概念,例如身份验证插件服务插件数据建模。虽然本系列文章会涵盖与所描述的用例相关的概念,但不可能面面俱到。

仪表板

为了展示持续不断的数据流,我将创建一个包含图表的简单仪表板。

创建仪表板视图

// /src/views/Dashboard.vue
<template>
  <main class="home container">
    <div class="row text-center">
      <h1>Dashboard</h1>
    </div>
    <div class="row">
      <div class="col-6">
        <h3>Messages Sent</h3>
        <BarChart :chart-data="barchartdata" :options="options" />
      </div>
      <div class="col-6">
        <h3>Active Chat Rooms</h3>
        <BarChart :chart-data="barchartdata2" :options="options" />
      </div>
    </div>
    <div class="row">
      <h3>Recent Logins</h3>
      <LineChart :chart-data="linechartdata" :options="options" />
    </div>
    <div class="row">
      <h3>Current Tasks</h3>
      <DonutChart :chart-data="donutchartdata" :options="doptions" />
    </div>
    <div class="row">
      <h3>DEBUG</h3>
      {{ serverMessage }}
    </div>
  </main>
</template>
Enter fullscreen mode Exit fullscreen mode

您可能会注意到此仪表板视图中添加了图表组件。我们将在下文中创建这些组件。

将视图添加到路由

const routes = [
... 
  { path: '/chat', name: 'Chat', component: Chat },
  { path: '/dashboard', name: 'Dashboard', component: Dashboard },
...
];
Enter fullscreen mode Exit fullscreen mode

在聊天视图中添加仪表盘链接

<div class="title-wrapper block center-element">
  <img
     class="logo"
     src="http://feathersjs.com/img/feathers-logo-wide.png"
     alt="Feathers Logo"
  />
  <span class="title">Chat</span>
</div>
<router-link class="float-right link" to="/dashboard">
    Dashboard
</router-link>
Enter fullscreen mode Exit fullscreen mode

显示数据

为了可视化数据流,我们将使用图表来显示数据更新。我将使用Charts.js的Vue 封装库vue-chartjs,它提供了一个简单而又可定制的图表库。

yarn add vue-chartjs chart.js

创建图表组件

vue-chartjs它可以轻松地在单个 Vue 组件文件中添加图表组件。查看文档了解更多关于如何在 Vue 应用中使用它的信息。

以下是条形图组件的示例。

// /src/components/BarChart.vue
<script>
import { Bar, mixins } from 'vue-chartjs';
const { reactiveProp } = mixins;

export default {
  extends: Bar,
  mixins: [reactiveProp],
  props: ['chartData', 'options'],
  mounted() {
    this.renderChart(this.chartData, this.options);
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

请确保包含 ` mixinsand` 和reactiveProp`.reactiveProp` mixin。`reactiveProp` mixin 会为chartData变量添加一个监视器,以便在数据更改时进行更新。

聆听事件

要为该事件创建事件监听器dataAvailable,请在 Dashboard 组件获取到某个值时添加事件监听器mounted(),并在 Dashboard 组件获取到另一个值时移除该事件监听器destroyed()。请查看以下代码,了解如何创建事件监听器:

  mounted() {
    // add an event listener to dataAvailable event
    this.establishConnection();
  },
  destroyed() {
    // remove the dataAvailable event listener
    this.destroyConnection();
  },
  methods: {
    destroyConnection() {
      feathersClient.io.off('dataAvailable');
    },
    establishConnection() {
      feathersClient.io.on('dataAvailable', (data) => {
        console.log('Receiving data from server: ', JSON.stringify(data));
        // update variables to the data received from the server
        this.messageCount = data.messageCount;
        this.recentLogins = data.recentLogins;
        this.activeChatRooms = data.activeChatRooms;
        this.openTickets = data.openTickets;
        this.closedTickets = data.closedTickets;
        this.unassignedTickets = data.unassignedTickets;
        this.serverMessage = data;
      });
    },
  },
Enter fullscreen mode Exit fullscreen mode

现在,当您运行 vue 应用并导航到该/dashboard页面时,您应该会看到图表每 5 秒更新一次。

检查你的作业

到目前为止的最终代码位于hello-world此仓库的分支上:https://github.com/meditatingdragon/realtime-feathers/tree/hello-world

升级:创建自定义指标服务

超越简单的“Hello World”示例,创建一个能够提供数据的自定义服务。Feathers 提供了一种简便的方法来为应用程序功能生成服务MetricsService。对于我们的仪表板,我们可以创建一个……

feathers generate service
Enter fullscreen mode Exit fullscreen mode
? What kind of service is it? A custom service
? What is the name of the service? metrics
? Which path should the service be registered on? /metrics
? Does the service require authentication? No
   create src/services/metrics/metrics.service.js
    force src/services/index.js
   create src/services/metrics/metrics.class.js
   create src/services/metrics/metrics.hooks.js
   create test/services/metrics.test.js
Enter fullscreen mode Exit fullscreen mode

将 MetricsService 定义为每 5 秒创建一次数据的自定义服务。

const { getRandomInt } = require("../../utils/dataGenerator");

/* eslint-disable no-unused-vars */
exports.Metrics = class Metrics {
  async create(data) {
    return data;
  }

  setup() {
    let logins = [
      getRandomInt(50, 70),
      getRandomInt(50, 70),
      getRandomInt(50, 70),
      getRandomInt(50, 70),
      getRandomInt(50, 70),
      getRandomInt(50, 70),
      getRandomInt(50, 70),
    ];

    setInterval(() => {
      console.log("Sending new data");
      logins.shift();
      logins.push(getRandomInt(50, 70));
      this.create({
        messageCount: getRandomInt(1000, 10000) + getRandomInt(0, 100),
        activeChatRooms: getRandomInt(5, 100),
        recentLogins: logins,
        openTickets: getRandomInt(0, 100),
        closedTickets: getRandomInt(0, 100),
        unassignedTickets: getRandomInt(0, 100),
      });
    }, 5000);
  }
};

Enter fullscreen mode Exit fullscreen mode

然后我们可以更新数据连接以使用该服务:

establishConnection() {
    feathersClient.service('metrics').on('created', data => {
        console.log('Receiving data from server: ', JSON.stringify(data));
        // update variables to the data received from the server
        this.messageCount = data.messageCount;
        this.recentLogins = data.recentLogins;
        this.activeChatRooms = data.activeChatRooms;
        this.openTickets = data.openTickets;
        this.closedTickets = data.closedTickets;
        this.unassignedTickets = data.unassignedTickets;
        this.serverMessage = data;
      });
    },
}
Enter fullscreen mode Exit fullscreen mode

检查你的作业

到目前为止的最终代码位于metrics-service此存储库的分支上:https://github.com/meditatingdragon/realtime-feathers/tree/metrics-service

接下来:频道

为了在以后的文章中处理实时事件,我们将使用频道功能。如果您想快速上手,请查看相关文档。

请告诉我——您将如何在应用程序中利用实时事件?

文章来源:https://dev.to/rachel_cheuk/getting-started-with-realtime-events-and-streaming-data-in-js-4j6l