前端的全栈混合之路Meteor篇:分布式数据协议DDP深度剖析
本文属于进阶篇,并不是太适合新人阅读,但纯粹的学习还是可以的,因为后续会实现很多个ddp的版本用于web端、nodejs端、安卓端和ios端,提前预习和复习下。ddp协议是一个C/S架构的协议,但是客户端也同时可以是服务端。
什么是DDP?
DDP (Distributed Data Protocol) 是Meteor框架中使用的一种简单而强大的发布/订阅协议。它允许客户端和服务器之间进行实时数据同步,是Meteor实现实时应用的核心技术之一。
DDP的主要特点
- 传输层灵活性: DDP可以基于WebSocket,也可以通过HTTP长轮询等方式实现,例如使用SockJS在不支持WebSocket的环境中工作。
- JSON格式: 所有的消息都使用JSON格式,便于解析和调试。-需要注意的是,实际的传输是用的EJSON进行序列化和反序列,从而支持了更多的对象传输,详参考 前端的全栈混合之路Meteor篇(四):支持自定义对象序列化的EJSON介绍
- 发布/订阅模型: 允许客户端订阅服务器端的数据集,并在数据变化时接收更新。它的应用例子见文章 前端的混合全栈之路Meteor篇(三):发布订阅示例代码及如何将Meteor的响应数据映射到vue3的reactive系统
- 方法调用: 客户端可以调用服务器端的方法,实现远程过程调用(RPC)。基于它的应用例子见文章 前端的全栈混合之路Meteor篇(二):RPC方法注册及调用
- 实时更新: 当订阅的数据发生变化时,服务器会自动将更新推送给客户端。这部分是和发布订阅关联的,本文会涉及到底层实现
- 会话管理: 使用会话ID来维护客户端和服务器之间的连接状态。
DDP协议的详细过程
1. 握手和连接建立
- 客户端发送
connect
消息,可能包含版本信息和会话ID(如果是重连)。 - 服务器回复
connected
消息,包含新的会话ID。 - 如果是重连,服务器会恢复之前的订阅和方法调用状态。
2. 保活和心跳机制
- 客户端定期(通常每45秒)发送
ping
消息。 - 服务器回复
pong
消息。 - 如果超时未收到
pong
,客户端可能会尝试重新连接。
3. 方法调用
- 客户端发送
method
消息,包含方法名和参数。 - 服务器执行方法,可能会触发数据变更。
- 服务器发送
result
消息,包含方法执行结果或错误信息。 - 如果方法导致数据变更,服务器会发送相应的
added
、changed
或removed
消息。
4. 发布和订阅
- 客户端发送
sub
消息,包含订阅名称和参数。 - 服务器开始发送相关数据:
added
消息用于新增的文档changed
消息用于更新的文档removed
消息用于删除的文档
- 服务器发送
ready
消息,表示初始数据集已发送完毕。 - 之后,服务器会持续发送
added
、changed
和removed
消息以保持数据同步。 - 客户端可以发送
unsub
消息来取消订阅。
DDP消息类型详解
-
connect: 客户端发起连接请求
{"msg": "connect", "version": "1", "support": ["1", "pre2", "pre1"]}
-
connected: 服务器确认连接成功
{"msg": "connected", "session": "RandomSessionId123"}
-
ping/pong: 心跳消息
{"msg": "ping", "id": "unique-id-123"} {"msg": "pong", "id": "unique-id-123"}
-
sub/unsub: 订阅和取消订阅
{"msg": "sub", "id": "random-id", "name": "publicationName", "params": []} {"msg": "unsub", "id": "random-id"}
-
added/changed/removed: 数据更新通知
{"msg": "added", "collection": "collectionName", "id": "documentId", "fields": {}} {"msg": "changed", "collection": "collectionName", "id": "documentId", "fields": {}} {"msg": "removed", "collection": "collectionName", "id": "documentId"}
-
ready: 初始数据加载完成通知
{"msg": "ready", "subs": ["subscription-id-1", "subscription-id-2"]}
-
method/result: 方法调用和结果
{"msg": "method", "method": "methodName", "params": [], "id": "call-id"} {"msg": "result", "id": "call-id", "result": {} }
DDP全生命周期时序图
可使用mermaid进行预览,时序图code如下
sequenceDiagramparticipant Clientparticipant Server%% 握手和连接建立Client->>Server: connect {version: "1", support: ["1", "pre2", "pre1"]}Server-->>Client: connected {session: "RandomSessionId123"}%% 发布订阅Client->>Server: sub {id: "sub1", name: "posts", params: []}Server-->>Client: added {collection: "posts", id: "post1", fields: {...}}Server-->>Client: added {collection: "posts", id: "post2", fields: {...}}Server-->>Client: ready {subs: ["sub1"]}%% 实时更新loop Real-time updatesServer-->>Client: changed {collection: "posts", id: "post1", fields: {...}}Server-->>Client: added {collection: "posts", id: "post3", fields: {...}}Server-->>Client: removed {collection: "posts", id: "post2"}end%% 方法调用Client->>Server: method {method: "addPost", params: [...], id: "m1"}Server-->>Client: added {collection: "posts", id: "post4", fields: {...}}Server-->>Client: result {id: "m1", result: {...}}%% 取消订阅Client->>Server: unsub {id: "sub1"}%% 心跳机制loop Keep-aliveClient->>Server: ping {id: "ping1"}Server-->>Client: pong {id: "ping1"}end
时序图预览
DDP在Meteor中的应用
- 实时数据同步: 当服务器端的数据发生变化时,客户端可以立即收到更新。
- 用户界面响应: 通过DDP,用户界面可以实时反映数据的变化,提供流畅的用户体验。
- 分布式计算: 客户端可以调用服务器端的方法,实现复杂的计算或数据处理。
- 多客户端协作: 多个客户端可以同时订阅相同的数据集,实现实时协作功能。
- 离线支持: 通过本地缓存和重连机制,DDP可以支持离线操作和数据同步。
总结
DDP协议是Meteor框架的核心组件之一,它为实时Web应用提供了强大而灵活的数据同步机制。通过使用DDP,开发者可以轻松构建响应迅速、实时更新的现代Web应用,同时保持了在不同网络环境下的适应性。
相关文章:

前端的全栈混合之路Meteor篇:分布式数据协议DDP深度剖析
本文属于进阶篇,并不是太适合新人阅读,但纯粹的学习还是可以的,因为后续会实现很多个ddp的版本用于web端、nodejs端、安卓端和ios端,提前预习和复习下。ddp协议是一个C/S架构的协议,但是客户端也同时可以是服务端。 什…...

基于Zynq SDIO WiFi移植一(支持2.4/5G)
基于SDIO接口的WIFI,在应用上,功耗低于USB接口,且无须USB Device支持,满足某些应用场景 1 硬件连接 2 Vivado工程配置 3 驱动编译 3.1 KERNRL CONFIG (build ENV) 修改 export KERNELPATH<path of kernel header>export T…...

数据结构与算法篇(刷题篇 - 链表)
目录 1. 反转链表(简单) 1.1. 题目描述 1.2. 解题思路 方法一:迭代(推荐使用) 方法二:递归(扩展思路) 方法三:使用栈解决 方法四:双链表求解 2. 链表内…...
TinyAgent: 从零开始构建最小化Agent系统
引言 随着大模型(LLM)的崛起,特别是ChatGPT等大模型的广泛应用,基于LLM的系统越来越受欢迎。然而,尽管大模型具备强大的生成能力和推理能力,它们在处理某些专有领域或实时问题时仍然存在局限性。因此&#…...

Android Studio New里面没有New Flutter Project
跟着Flutter中文网的配置教程,安装好了flutter,在Android studio里面也安装了dart和flutter的插件。重启后还是在FIle->New里面没有显示New Flutter Project。 反复卸载重装dart和flutter插件好几次,依然没有效果。 原来是没有把Android APK Suppor…...

linux信号 | 学习信号四步走 | 透析信号是如何被处理的?
前言:本节内容讲述linux信号的捕捉。 我们通过前面的学习, 已经学习了信号的概念, 信号的产生, 信号的保存。 只剩下信号的处理。 而信号的处理我们应该着重注意的是第三种处理方式——信号的捕捉。 也就是说, 这篇文章…...

mysql语句执行过程
具体流程如下: 1】当客户端的SOL发送到MySQL时,首先是到达服务器层的连接器,连接器会对你此次发起的连接进行权限校验,以此来获取你这个账号拥有的权限。当你的账号或密码不正确时,会报用户错误。连接成功如果后续没有任何操作&am…...

最新版本SkyWalking【10.1.0】部署
这里写目录标题 前言前置条件启动Skywalking下载解压启动说明 集成Skywalking Agent下载Agent在IDEA中添加agent启动应用并访问SpringBoot接口 说明 前言 基于当前最新版10.1.0搭建skywalking 前置条件 装有JDK11版本的环境了解SpringBoot相关知识 启动Skywalking 下载 地…...
WSL2 中配置桥接模式、虚拟交换机及固定 IP
WSL2 中配置桥接模式、虚拟交换机及固定 IP 一、创建虚拟交换机1.1 使用 Hyper-V 管理器创建虚拟交换机1.2 使用 PowerShell 创建虚拟交换机 二、更新 WSL 配置三、设置 WSL2 中的静态 IP、网关和 DNS3.1 编辑网络配置文件3.2 应用网络配置3.3 测试网络连接 四、重启 WSL 在使用…...

Unite Shanghai 2024 团结引擎专场 | 团结引擎 OpenHarmony 工程剖析
在 2024 年 7 月 24 日的 Unite Shanghai 2024 团结引擎专场演讲中,Unity中国 OpenHarmony 技术负责人刘伟贤对团结引擎导出的 OpenHarmony 工程进行了细节剖析,详细讲解 XComponent 如何与引擎结合,UI 线程和引擎线程的关联以及 ts/ets 的代…...

计算机毕业设计 基于Hadoop的智慧校园数据共享平台的设计与实现 Python毕业设计 Python毕业设计选题 Spark 大数据【附源码+安装调试】
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...
2022CCPC绵阳站VP题解报告(CGHMAE六题)
文章目录 2022CCPC绵阳站VP题解报告前言[Problem - C ](https://codeforces.com/gym/104065/problem/C) (签到思维)[H (codeforces.com)](https://codeforces.com/gym/104065/problem/H) (签到构造)[Problem - G ](https://codefo…...
代码随想录day23:贪心part1
455. 分发饼干 class Solution {public int findContentChildren(int[] g, int[] s) {Arrays.sort(g);Arrays.sort(s);int res 0;int index s.length - 1;for(int i g.length - 1; i > 0; i--){if(index > 0 && s[index] > g[i]){res;index--;}}return r…...
通过网页设置参数,submit还是json
在通过网页设置参数并发送到服务器时,选择使用submit(通常是通过HTML表单的提交)还是直接发送JSON数据(通常是通过AJAX请求,如使用fetch API)取决于几个因素,包括你的服务器端如何处理这些请求、…...

C语言 | Leetcode C语言题解之第463题岛屿的周长
题目: 题解: const int dx[4] {0, 1, 0, -1}; const int dy[4] {1, 0, -1, 0};int dfs(int x, int y, int** grid, int n, int m) {if (x < 0 || x > n || y < 0 || y > m || grid[x][y] 0) {return 1;}if (grid[x][y] 2) {return 0;}g…...
逼近理论及应用精解【12】
文章目录 卷积卷积层与滤波层定义数学原理与公式定理架构例子例题 卷积层和滤波层概念的详细解释卷积层滤波层 滤波层和卷积层在卷积神经网络(CNN)中区别滤波层卷积层总结卷积层的数学原理滤波层的数学原理 参考文献 卷积 卷积层与滤波层 定义 卷积层…...

LIN总线学习大全(基于CANoe和CAPL)
🍅 我是蚂蚁小兵,专注于车载诊断领域,尤其擅长于对CANoe工具的使用🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】🍅 玩转CANoe&…...

国庆作业
day1 1.开发环境 Linux系统GCCFDBmakefilesqlite3 2.功能描述 项目功能: 服务器:处理客户端的请求,并将数据存入数据库中,客户端请求的数据从数据库进行获取,服务器转发给客户端。 用户客户端:实现账号的注册、登…...

Android OpenGLES2.0开发(四):矩阵变换和相机投影
事物的本质是事物本身所固有的、深藏于现象背后并决定或支配现象的方面。 还记得我们上一篇绘制的三角形吗,我们确实能够顺利用OpenGL ES绘制出图形了,这是一个好的开始,但这还远远不够。我们定义的坐标是正三角形,但是绘制出…...

快递查询软件:实现单号识别与批量物流查询的高效工具
随着网络购物的普及,快递物流行业迎来了前所未有的发展机遇,同时也面临着巨大的挑战。跟踪物流信息成为一个难题,因此,快递查询软件的核心功能之一便是单号识别。传统的快递单号输入方式繁琐且易出错在此背景下,快递查…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...