总结[设计] 如何设计大屏同步方案

大致的需求就是,在客户现场展示几个大屏,而客户可以在管理端控制每个大屏的展示布局。

那么针对这种情况我们应该如何设计呢?

首先我们使用的方案是websocket长连接方案。因为在这个需求总管理端需要知道连接的每个大屏的状态,而客户端需要实时同步大屏数据和上报自身状态同步给客户端。

对此使用长连接通讯相对来讲是比较靠谱的而且很容易实现。

在这里我们虽然展示了不同的大屏,但是每个大屏默认会有一个初始配置,用于首次展示。

那么这种展示方式的连接流程数据交方式是什么?

首先我们的连接流程指的是对接websocket的连接流程,在此我们规定了如下格式

go 复制代码
type DataMessage struct{
  PageId:      string `json:pageId`,      // 页面唯一标识
  PageStatus:  int    `json:pageStatus`   // 页面的类型 1 管理端 | 2 展示端
  PageVersion: int    `json:pageStatus`   // 页面配置版本
  Data:        string `json: data`        // 同步的数据
}

在页面连接之前会自己生成一个md5表示当前的页面ID,这条数据也用于存储该页面对应socket连接的key值,这样设计的关键点是对需要广播的配置页面实现精准控制,保证每个配置的独立性。数据结构如下

go 复制代码
type pageWebsocket struct {
	PageId       string          `json:pageId`        // 唯一标识
   PageStatus:  int             `json:pageStatus`    // 页面的类型 1 管理端 | 2 展示端
   PageVersion: int             `json:pageStatus`    // 页面配置版本
	ws           *websocket.Conn `json:ws`            // 版本号
}
var pageWebsocketMap = map[string] pageWebsocket{}   // 数据map

假设我们有四个展示端页面一个管理端,在一开始进入的时候会产生5条连接,每个连接均通过上述方式记录,此时,管理端会接收到由四个页面同步过来的数据,并展示在管理页面中,每次配置时端可以批量选择需要同步的页面,被选中的页面的pageId就会被作为广播的发送者,通过之前pageWebsocketMap存储的ws连接句柄来广播数据。

展示端如果需要同步自身数据,需要通过PageStatus找到管理端实现管理端的数据广播(我们目前做的是只有一个管理端页面,不存在多管理端控制同一页面)。

每次窗口关闭时释放pageWebsocketMap存储的长连接,而针对释放我们采取的是服务端生成一个唯一标识,该标识仅仅标识本次连接是唯一的,用于defer函数回调时使用

对于客户端使用store来做数据管理,格式如下所示

typescript 复制代码
interface State {
  ws: WebSocket | undefined;
  isConnect: boolean;
  data: any;
}

export default createStore<State>({
  state: {
    ws: undefined,    // ws句柄
    isConnect: false, // 是否连接
    data: {},         // 数据
  },
  getters: {},
  mutations: {
    setData(store, payload: WebSocket) {
      store.data = payload;
    },
    setWs(store, payload: WebSocket) {
      store.ws = payload;
    },
    setState(store, payload: boolean) {
      store.isConnect = payload;
    },
  },
  actions: {
    initWebsocket(store, userId: string) {
      if (
        store.state.ws &&
        store.state.ws.CLOSED !== 3 &&
        store.state.isConnect
      ) {
        store.state.ws.close();
      }
      const ws = new WebSocket(WS_URL);
      store.commit("setWs", ws);
      ws.onopen = () => {
        store.commit("setState", true);
        const params = JSON.stringify({ userId, type: 1 });
        store.commit("setData", params);
      };
      ws.onerror = () => {
        store.commit("setState", false);
      };
      ws.onclose = () => {
        store.commit("setState", false);
      };
      ws.onmessage = (ev: MessageEvent<any>) => {
        store.commit("setData");
        const data = JSON.parse(ev.data);
        console.log(data);
      };
    },
    sendData(store, jsonData: any) {
      if (store.state.ws) {
        store.state.ws.send(JSON.stringify(jsonData));
      }
    },
  },
  modules: {},
});

该函数仅仅起到ws的透传管理,具体的数据发送依靠sendData实现,而响应则是依靠onmessage来作为数据的同步,页面使用computed或直接使用useStore获取数据即可完成页面的动态刷新操作

相关推荐
小信丶7 分钟前
解决 pnpm dev 报错:系统禁止运行脚本的问题
前端·vue.js·windows·npm
૮・ﻌ・14 分钟前
Vue3:组合式API、Vue3.3新特性、Pinia
前端·javascript·vue3
前端不太难15 分钟前
RN + TypeScript 项目越写越乱?如何规范架构?
前端·javascript·typescript
神算大模型APi--天枢64615 分钟前
全栈自主可控:国产算力平台重塑大模型后端开发与部署生态
大数据·前端·人工智能·架构·硬件架构
苏打水com15 分钟前
第十五篇:Day43-45 前端性能优化进阶——从“可用”到“极致”(对标职场“高并发场景优化”需求)
前端·css·vue·html·js
@大迁世界23 分钟前
08.CSS if() 函数
前端·css
Moment30 分钟前
小米不仅造车,还造模型?309B参数全开源,深度思考完胜DeepSeek 🐒🐒🐒
前端·人工智能·后端
苏打水com33 分钟前
第十六篇:Day46-48 前端安全进阶——从“漏洞防范”到“安全体系”(对标职场“攻防实战”需求)
前端·javascript·css·vue.js·html
5C2435 分钟前
从思想到实践:前端工程化体系与 Webpack 构建架构深度解析
前端·前端工程化
咕噜企业分发小米41 分钟前
如何平衡服务器内存使用率和系统稳定性?
java·服务器·前端