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

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

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

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

相关推荐
nbsaas-boot21 分钟前
消息队列场景下的前端设计:如何优化用户体验
前端·ux
sususugaa24 分钟前
前端框架Vue3——响应式数据,v-on,v-show和v-if,v-for,v-bind
开发语言·前端·vue.js·前端框架
珹洺2 小时前
从 HTML 到 CSS:开启网页样式之旅(三)—— CSS 三大特性与 CSS 常用属性
前端·javascript·css·网络·html·tensorflow·html5
T^T尚6 小时前
uniapp H5上传图片前压缩
前端·javascript·uni-app
出逃日志7 小时前
JS的DOM操作和事件监听综合练习 (具备三种功能的轮播图案例)
开发语言·前端·javascript
XIE3927 小时前
如何开发一个脚手架
前端·javascript·git·npm·node.js·github
山猪打不过家猪7 小时前
React(五)——useContecxt/Reducer/useCallback/useRef/React.memo/useMemo
前端·javascript·react.js
前端青山7 小时前
React事件处理机制详解
开发语言·前端·javascript·react.js
科技D人生7 小时前
Vue.js 学习总结(14)—— Vue3 为什么推荐使用 ref 而不是 reactive
前端·vue.js·vue ref·vue ref 响应式·vue reactive
对卦卦上心7 小时前
React-useEffect的使用
前端·javascript·react.js