公司做过智慧景区相关的可视化数据大屏,为了后期统一管理和维护,我们做成了SaaS可视化数据平台,每个租户可以有自己的模版库,第一期我们没有做前端设计大屏模版,模版全是内置进去(模版模块信息和模块数据类型结构),第二期考虑前端设计模版。当选择模版创建项目后,可配置项目相关信息(项目名称,访问密码,socket连接等),模版模块数据源配置(有多种数据源进行选择)。我们数据源类型只使用静态和WS,并使用netty创建websocket服务进行通讯,后端通过MQ进行解耦,netty服务监听MQ消息并把数据推送给前端
查看 大屏通讯流程图及大屏模版
数据源类型
- 静态:后端进行数据编辑或导入 [后端变更数据后实时socket推送返回]
- API:配置后端接口地址,调用频率 [前端定时执行API后返回(很少前端会这样干、显得很low),还不如后端定时推送)]
- SQL:配置选择数据源,调用频率,sql语句 [前端定时执行相关后端接口返回、或者后端定时执行sql 任务后推送]
- WS:配置socket数据key [后端socket推送返回]
安全性
- 链接安全性:对参数加密,比如项目ID参数:projectId,我们简单使用 aes对称性加密方式进行加密
- 访问安全性: 设置是否需要访问密码,需要的话需要输入访问密码访问(可用于分享链接)
- 数据安全性: 我们简单使用aes对称性加密方式对返回数据进行加密,前端解密
推送的数据如何与模块对应
每个模块都有唯一的key,推送数据的时候会带上数据key ,前端根据不同的key匹配,进行数据展示
数据key可以是:
- 每个模块标识内置的唯一key(内置模版的时候已经知道)
- 数据源类型为WS时设置的socket数据key,没有设置则默认为模块内置key
大屏链接访问
如大屏链接:http://127.0.0.1:9999/view/3895fd02996883678503ed69f2418092
ws连接:ws://127.0.0.1:36101/v1?project=3895fd02996883678503ed69f2418092
如何确认数据推送给那个项目的那个客户端
- 大屏项目与ws建立连接后,分配一个客户端ID,存储客户端Channel关系
- 建立连接握手后,返回客户端信息,每次客户端请求必须带上客户端信息
- 推送的时候从存储中找到客户端对应的Channel并进行数据推送
客户端Channel存储及查找
不考虑netty集群(简单)
存储数据类型: ConcurrentHashMap: key =projectId +":"+clientId,value = Channel对象
考虑netty集群
因为Channel对象存储到redis反序列化不到真正的Channel对象,除非不把value进行序列化操作,但是一般redis存储时都会进行序列化,所以我们换一种存储形式,即存储Channel的ChannelId的asLongText对象,在通过asLongText查找netty服务中Channel,本netty服务找不到,再MQ广播其它Netty服务进行查找。
存储数据类型:
redis Hash: key =projectId +":"+clientId,value = ChannelId的asLongText对象
ConcurrentHashMap: key = ChannelId的asLongText对象,value = Channel对象
Channel中的Attribute对象中存储信息(如客户端信息)
Hannler可以从Channel中的Attribute对象中获取存储的信息
何时存储和移除客户端和Channel
存储:安全校验通过握手成功后存储客户端和Channel关联信息
移除: channelInactive 、exceptionCaught 方法中移除客户端和Channel关联信息、关闭服务的时 候移除
如何保证客户端服务端通讯正常并有效
建立心跳机制,客户端和服务器之间定期发送的一种特殊的数据包,通知对方自己还在线,以确保 TCP 连接的有效性