持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情
写在前面
前面三篇文章,已经从最基础的角度介绍了低代码相关技术的实现方式,我们已经能够做到通过拖拽添加组件、以及通过可视化界面直接配置组件的各种参数,那么当我们完成了这些技术的探索之后呢,基本上界面的编辑就没啥问题了,后续只需要扩充组件库,也就能够支持更多的组件编辑了。
当组件拖拽和参数配置已经完成后,接下来就到了关键的问题了,当编辑完界面后,那么就应该给静态页面加上数据了,那么如何对接数据呢,接下来就让我们一起来探索探索!!
接入方式
这几篇文章主要以排版布局以及业务逻辑较为简单的“数字孪生可视化”项目为例子,来探索低代码,那么数据接入也依然采用“数字孪生可视化”项目常用的接入方式 Websocket 来进行对接
Websocket 是什么
WebSocket 是一种在单个 TCP 连接上进行 全双工 通信的协议。WebSocket通信协议于2011年被[IETF]定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被 W3C 定为标准。
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
如果对于Websocket 这种通信协议还不是很了解的话,可以看看我之前的文章 面试官:除了 HTTP,你还用过什么通信协议?(Websocket 在数字孪生中的应用)
Websocket 如何控制推送的数据
当我们需要通过 Websocket 来给页面上的所有组件做数据推送时,那么这个时候也就不能采用之前文章中的所采用的那种判断方式了,必须对双方接、收的消息进行分类、整理。
通常,Websocket 采用的数据推送方式是“开始订阅--间歇性推送”,也就是说客户端需要在开始阶段告诉服务器,他需要什么数据,也就是向客户端发送订阅列表,然后服务器接收到订阅列表后开启定时器,定时向客户端推送订阅的数据,最后,当客户端收到服务器推送的消息时,通过客户端与服务器约定的标准识别方式识别每个数据相对应的组件,最后进行前端渲染,至此,数据订阅完成。过程图解如下
服务器实现
基础实现在之前的文章已经做过详细介绍,这里只分析订阅相关的功能模块,连接相关的代码略过
连接相关代码
// 引入 ws 模块
const WebSocket = require('ws');
// 创建 server 实例并监听 3000 端口
const server = new WebSocket.Server({host:'localhost',port:3000},()=>{
console.log('WebsocketServer Start !')
});
server.on('connection',(client)=>{
console.log('连接成功')
// 添加消息回调
client.on('message',(msg)=>{
console.log('message', msg);
// 开始数据监听,当数据更新时想客户端推送数据
startMonitor(client, JSON.parse(msg))
})
})
订阅相关代码
这里使用 getData(id)
来模拟获取 id
对应的数据,当在 Websocket 的监听消息中监听到了客户端发送的订阅列表后,调用 startMonitor 模拟监听指定数据,并启动定时器,每5s向客户端推送一次数据。
getData
产生的数据格式为 id + data
,其中的 id
就是客户端用来识别数据与组件对应关系的标识。
function startMonitor(client, dataList){
setInterval(() => {
dataList.forEach(ele => {
// 创建模拟数据
let data = getData(ele)
client.send(JSON.stringify(data))
})
}, 1000 * 5);
}
function getData(id){
let data = {
id: id,
data: `${Math.floor(Math.random()*100)}`
}
return data
}
客户端实现
由于服务器向客户端推送消息的时候,无论订阅了多少,推送都是无差别推送,因此,在客户端需要自己进行判断,对收到的消息的标识进行区分,并与事先定义好的订阅列表做匹配,最后更新到相应的组件上,方可完成组件数据更新,代码如下
<template>
<div class="websocket-container">
<div class="ws-box box1">
<CPN1 :currentData="data1"/>
</div>
<div class="ws-box box2">
<CPN2 :currentData="data2"/>
</div>
</div>
</template>
<script>
import CPN1 from '../components/CPN1.vue';
import CPN2 from '../components/CPN2.vue';
export default {
components: {
CPN1,
CPN2
},
data() {
return {
data1: '0',
data2: '0',
dataList: {
'1-1': 'data1',
'2-2': 'data2'
}
}
},
methods: {
initWebsocket(){
this.ws = new WebSocket("ws://localhost:3000");
//服务端向客户端连接执行
this.ws.onopen = ()=>{
console.log('连接建立')
this.sendDataList()
}
this.ws.onmessage = (msg) => {
console.log('收到消息:', msg.data)
this.update(JSON.parse(msg.data))
}
},
// 更新数据
update(data){
console.log(data)
this[this.dataList[data.id]] = data.data
},
// 订阅
sendDataList(){
console.log('sendDataList')
let list = Object.keys(this.dataList)
this.ws.send(JSON.stringify(list))
}
},
mounted() {
this.initWebsocket()
},
}
</script>
效果展示
总结
在这一篇中对数据订阅相关的架构进行了分析,使得我们能够更加灵活地使用 Websocket 进行相关项目的开发,也将低代码平台又先前推动了一小步,通过近四篇低代码相关的文章的分析,将所有的技术加以融合,基本上已经满足搭建一个简易版数字孪生低代码平台的基础条件了,相信完整版的数字孪生低代码平台已经离我们越来越近了,大家一起加油吧!
往期好文推荐
面试官:说说从输入 URL 到页面显示到底经历了什么,体现一下你的知识广度
面试官:HTTPS 采用的是对称加密还是非对称加密?具体说说其加密过程
面试官:你就只会 npm run build 吗?(Webpack 配置 Vue+Ts)
面试官:连VuePress都没搭过还说开发过组件库?(VuePress 搭建)
面试官: 连 Vue 视图更新都不会写?(Vue视图更新原理【一】)
面试官: 能不能手写 Vue 响应式?(Vue2 响应式原理【完整版】)
面试官:能不能手写 Vue3 响应式(Vue3 原理解析之响应系统的实现)
面试官:说一下这个Loading动画实现思路 (CSS3 实现 Loading 动画)
面试官:你确定你说的防抖不是节流吗?( 面试题梳理系列 (二))
面试官:除了 HTTP,你还用过什么通信协议?(Websocket 在数字孪生中的应用)
面试官:你真的理解 Event Loop 吗?( JS 事件循环 )
面试官:v-for 中 key 为什么不能用 index,从原理层面聊聊?
面试官:vue-router 的 hash 与 history 哪个模式会刷新页面?
面试官:说说你平时用过的自适应方案(数字孪生可视化自适应方案)
写在最后
博主接下来将持续更新好文,欢迎关注博主哟!!
如果文章对您有帮助麻烦亲点赞、收藏 + 关注和博主一起成长哟!!❤️❤️❤️