会议签到系统的架构和实现
摘要:通过定制安卓会议机开机APP呈现签到界面,并且通过W/B结构采集管理签到信息,实现会议签到的功能。为达到此目标本文将探讨使用Redis提供后台数据支持;使用SocketIo处理适时消息;使用Flask进行原型开发;使用Rust的Axum框架对Web访问进行优化等各个方面。
关键词:会议机、签到、反向代理、KV数据库、Redis、Flask、Axum
目录
一、 组织框架
二、功能实现
1、 安卓启动软件定制
2、 Caddy配置
3、 Flask和Redis交互
4、 简要介绍前端Vue
5、 Rust对核心代码的优化和配置
6、 SocketIO适时响应的作用
三、安装和部署
四、总结
一、 组织框架
我们使用长安视讯的会议机某个系列,使用的是安卓版本7.0定制系统,兼容安卓软件,通过定制开机App,可以实现开机画面显示本站签到人员信息,对其的点击,提交到WEB端及Redis数据库,这就是本系统的基础处理流程。
Caddy作为代理,提供灵活配置和故障冗余,对于Rust替换Flask实现特定功能特别有用,而对于容器后面的Flask服务也用于提供remoteIP的必要属性。
WEB服务器使用Flask,通过逐层添加模块,最终实现签到人员采集,设备状态监控,存储分配名单等等功能。
Redis提供一个数据存储,保存并提供车站人员信息、设备IP绑定等。
最终为了签到提速,使用Rust跨平台二进制程序,分离部分签到接口,建立适时快速的签到通道。
二、功能实现
1、 安卓启动软件定制
将安卓启动软件项目AnyLaucher下载到本地,安装Android Develop Tools工具链,修改界面加入WebView控件,删除无用代码和按钮。在程序启动函数加入上线检测和页面加载代码:
完成以后的界面:
2、 Caddy配置
反向代理flask:
代理socketio:
3、 Flask和Redis交互
引用和初始化:
from flask_redis import FlaskRedis # 使用flask-redis库
app = Flask(__name__)
app.config['SECRET_KEY'] = 'top-secret!'
app.config['REDIS_URL']="redis://:pass@ip:6379/9"
app.config['WERKZEUG_RUN_MAIN']=True #
cl.init_app(app)
操作实例,将IP到车站名的字典存入和取出:
def redis2ipdic():
global ipdic
ipdic.clear()
for k,v in cl.hgetall(IPDIC_KEY).items():
ipdic[k.decode() ]=v.decode()
return ipdic
def ipdic2redis():
global ipdic
# 将字典保存到Redis的哈希中
cl.delete(IPDIC_KEY)
cl.hmset(IPDIC_KEY,ipdic)
最后Flask实现汇总点名信息界面如下:
4、 简要介绍前端Vue
在开发过程中,车站人名列表是个灵活改变的项目,需要一个web端的维护界面,于是用到了Vue3,NativeUI组件。其开发文档比较全面。最后绑定Flask后端的json数据,并且将更新提交到Flask的更新接口。
全部车站的人员模板:
保密+脑补1
单个车站编辑:
保密+脑补2
实现汇总打印的界面:
保密+脑补3
5、 Rust对核心代码的优化和配置
Rust在同一时间可以响应更多的请求,使用了异步请求模式可以更快响应请求。
会议机请求页面在初始开发时,点击人名是整页刷新,在切换Rust过程中,修改为Ajax局部刷新、只变更本站最新人名列表和状态,
这两项修改压缩单次请求处理时间2倍以上。
A.Rust使用Axum实现签到功能后的大小5M上下,可以跨平台部署在多个节点,Caddy只需修改App首页链接的跳转地址,就可完成切换。遇到故障或错误,可随时调整到原来的Flask接口。
B.Caddy的负载均衡配置如下:
redir /ck/test /rk/test
handle /rk/* {
reverse_proxy {
header_up Host {host}
header_up X-Real-IP {remote}
health_uri /
health_interval 60s
health_timeout 1s
to 10.80.133.00:6055 192.168.1.00:3001
}
}
其中 /ck/test是默认安卓启动页, /rk/test是Rust程序接口,所有的/rk请求转向Rust的Axum服务。并且被部署在两个节点10.80.133.00:6055 192.168.1.00:3001,轮流接受请求。使用主动健康检查,60秒检查一次。如果其中一个离线,所有请求使用在线的另一个。
6、 SocketIO适时响应的作用
在开发过程中由于需要即时适时采集车站会议机人名,使用刷新轮询无疑会影响速度和性能。因此引入WebSocket的实现Flask-SocketIO,它能很方便的引入现有的Flask应用。
cl.init_app(app)
message_queue= app.config['REDIS_URL']
socketio = SocketIO(app, async_mode='threading',cors_allowed_origins='*' ,message_queue= app.config['REDIS_URL'])
SokcetIO用途
1. SocketIO的js客户端支持断线重连,长期在线,即便AnyLauncher处于后台也能从socketio-client判断会议机开关机状态。
2. 车站签到人名点击后,会控端首页和状态页可以收到消息通知,刷新签到信息。
3. 车站会前开机未签到,会收到会前提醒。在页面加载时通过null消息订阅,若有消息到达,则调用Android在WebBrowser接口toast显示提醒签到的消息。
注意事项:SocketIO一个限制是不能再多开工作进程,无法使用gunicorn的多worker, Rust使用socketioxide实现同样功能,并且完成了上线运行,作为优化的一部分。
三、安装和部署
本软件需要安装以下部分:
1、会议端APP,以apk发布,安装于会议机,并设置为开机启动,安装前需要把web默认申请地址内置于apk。
2、Web服务器需要安装Caddy,设为开机启动,对CaddyFile文件进行适当修改。
3、安装python3,较新版本及所需依赖,主要是Flask,推荐安装gunicorn以用于生产环境。安装完成后运行本app。
4、安装和运行Redis服务,然后修改Flask连接参数。
5、视情况运行Axum二进制服务,以提高响应速度,改变Caddy的配置文件,并重启Caddy服务。
四、总结
本文提供了安卓会议机实现签到功能的方案,本方案包含前后端实现,有较为灵活的编码架构以方便增改功能,使用Flask和Vue提供按需定制;也有较高的性能冗余,可以提供成百上千的同时访问,由Rust的二进制web服务支持。文中对技术细节和配置文件做了详细讲解,据此每个安卓会议系统的用户,可以实现符合自己需求的量身定制的签到系统。
本项目在开发过程中重度使用了百度AI问答和Github开源项目,并得到了长安视讯及本部门同事的大力支持,特此感谢。
参考资料:
1) Flask文档
2) Rust程序设计语言-简体中文版
3) Redis使用说明
4) Caddy2中文文档
5) Flask-socketio文档