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

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

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

首先我们使用的方案是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获取数据即可完成页面的动态刷新操作

相关推荐
Justinc.2 分钟前
CSS3新增边框属性(五)
前端·css·css3
neter.asia18 分钟前
vue中如何关闭eslint检测?
前端·javascript·vue.js
~甲壳虫19 分钟前
说说webpack中常见的Plugin?解决了什么问题?
前端·webpack·node.js
光影少年38 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_39 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
susu108301891141 分钟前
vue3 css的样式如果background没有,如何覆盖有background的样式
前端·css
Ocean☾42 分钟前
前端基础-html-注册界面
前端·算法·html
Dragon Wu44 分钟前
前端 Canvas 绘画 总结
前端
CodeToGym1 小时前
Webpack性能优化指南:从构建到部署的全方位策略
前端·webpack·性能优化
~甲壳虫1 小时前
说说webpack中常见的Loader?解决了什么问题?
前端·webpack·node.js