基于Netty+WebSocket的社区增值服务平台的推送设计
扫描二维码
随时随地手机看文章
引 言
随着人们逐渐从PC 解放,需求开始转移到移动设备的应用上。目前福建地区的小区住户、物业和周边配套服务都还处于离散状态,人们迫切希望有一款基于移动设备的智能社区服务平台,可以通过该系统方便住户随时获取小区的重要资讯, 了解住宅的实时情况,监控和控制住宅内的电器设备。而小区周边的其他配套服务系统可以通过该平台提供的接口直接与平台对接,向住户提供服务。
1 系统设计原理图
本系统建立在J2EE 平台上,运用 MySQL 数据库管理系统将 JSON 解析与 Netty、WebSocket 等技术相结合,构建更加智能的社区增值服务平台。社区增值服务系统搭建在云平台之上,充分利用现代化信息技术手段实现社区管理及服务的信息化、集约化,依托云平台的理念和优势,将已有的专业系统纳入其中,为社区居民、物业管理、周边服务机构提供便利丰富的终端服务。系统设计原理图如图 1 所示。
该平台的亮点是信息的分类推送,开发之前对信息推送的两种方式进行分析:
(1)第一种是客户端使用 Pull(拉)的方式,即定时到服 务器上获取,看是否有更新的信息。
(2)第二种是服务器使用 Push(推送)的方式,把最新 的信息 Push 到客户端上。
虽然 Pull 和 Push 两种方式都能实现获取服务端更新信 息的功能,但 Push 方式比 Pull 方式更优越 [1,2]。
本文通过对比分析国内现有的移动设备推送解决方案, 采用 Netty+WebSocket 持久连接的方式,实现了消息的实时 性推送和分类推送。
2 推送与控制实现
平台可实现系统用户的需求,如查看家中的光照强度、室内温度、空气湿度、烟雾浓度等实时数据,并对家中的家居进行控制操作,对硬件与手机之间的链接通信进行了详细合理的设计。Netty 与WebSocket 的结合完美解决了此通路问题,为实现平台的实时推送和分类推送奠定了基础。
(1) NettyServer集成了WebSocketClient,用来实现与各硬件之间的数据传送,NettyServer在初始化时与WebSocket Server建立长链接;
(2) WebSocketServer实现了与集成在 Netty服务器中的WebSocketClient之间的数据传送以及与用户手机端(或网页) 的交互。
推送和控制详细设计原理图如图 2 所示。
平台将传感器的数据推送到用户的流程描述 :单片机采集各传感器的实时数据,将这些数据通过 TCP上传到Netty 服务器, 当TCP 与 Netty 服务器第一次建立连接时, 触发channelActive() 方法建立通道,该通道在传感器断开之前一直存在,此后传感器定时发送数据,并直接触发channelRead0() 方法接收, 接收到的数据由集成在本服务器的WebSocket Client 模块处理, 通过 WebSocketClient.send() 方法发送给WebSocket 服务器,WebSocket 服务器中的WebSocket Server 通过onMessage() 方法接收,接收到实时数据后,则由 client. session.getBasicRemote().sendText(msg) 将数据推送给手机或网页终端。
Netty 服务器采用多线程服务器,对于每一个连接请求, dispatcher 都会为其创建并分配一个线程,该线程负责这个请求的处理,优点是执行粒度是完整的处理流程,处理逻辑清晰,易于开发。但也存在随着处理请求的不断增加,会导致并发执行的线程数量太多等问题。过多的线程数量会导致系统在线程调度和资源争用上的开销过大,从而引起系统性能急剧下降,导致系统处理能力下降。该平台采用了改进措施, 引入线程池,系统最多只能创建一定数量的线程,该平台规定最多能创建的线程数量为 100。当所有线程都饱和运行时,新到达的处理请求只能等待或者被抛弃。
在实现WebSocket的链接过程中,客户端和普通的浏览器都通过 80 或者 443端口和服务器进行请求握手,服务器根据 httpheader识别是否是一个WebSocket请求,如果是, 则将请求升级为一个WebSocket连接,握手成功后就进入双向长连接的数据传输阶段。WebSocket的数据传输基于帧方式:0x00表示数据开始,0xff表示数据结束,数据以utf-8 编码。第一次请求客户端发送的是http请求,请求头中包含WebSocket相关的信息,服务器端对请求进行验证,验证成功后,将请求升级为一个WebSocket连接,之后的通信就进入双向长连接的数据传输阶段,通过send和onMessage方法通信。
2.2 分类推送
平台采用 WebSocket 协议不仅实现了 Netty 服务器与WebSocket 服务器的实时通信,在分类通信上也做了一定尝试, 如推送工作,推送给哪一类型的用户,可以根据数据的格式来进行划分,在本平台中只做了初步划分,如数据格式为:{"from":"SMSG","room":"1201","temperature":"1","humidity":"2
.0","smoke?":"3"}(JSON形式), 从 room字段可以知道该数据是准备传送给 1201室的用户,目前平台只做了这个分类, 平台的下一步工作将在数据的格式上进行进一步细化和分类, 如按不同的楼栋,甚至不同的楼层分类,在分类推送上完善平台的功能。
2.3 JSON格式通信
JSON是一种轻量级数据交换格式,它采用完全独立于语言的文本格式,此特性使JSON成为理想的数据交换语言, 易于阅读和编写,同时也易于机器解析和生成,提升网络传输速率。本平台的各数据通信环节均采用JSON格式通信,使用对象和数组两种结构。对象在JSON格式表示为 { } 中的内容,数组在JSON格式是中括号 [ ] 中的内容,通过这两种结构可以表示各种复杂的结构[3]。
例如在 Netty 服务器将这些数据组织成 JSON 格式:{ "from":"SMSG","room":"1201","temperature":"1","humidity":"2.0","smoke?":"3"},WebSocketServe接收到数据后根据数据的格式进行判断,该数据由Netty服务器发送过来,可立即根据room找到对应的目标用户,读取其中的温度、湿度和烟雾值, 并推送数据。
2.4 控制实现
当用户发送控制信息时,数据又是如何从手机终端到达控制设备的呢?这个流程和 2.1 中介绍的推送流程相反。值得一提的是,WebSocket 服务器中的 WebSocket Server 通过onMessage() 方法接收, 接收的数据有可能是 Netty 服务器或手机终端发送的,WebSocket Serve 接收到数据后根据数据的格式进行判断, 根据不同的要求往不同的目标发送, 都由client.session.getBasicRemote().sendText(msg) 完成, WebSocket 服务器在推送和控制的过程中充当了一个重要的转接角色。
3 Android客户端设计
3.1 Service组件
在Android 中使用Service 服务组件作为通信服务层的组件。Service 服务运行于应用程序的后台,适合运行长期执行的操作。为了实现消息的及时接收,需要将 WebSocket 通信模块放在后台服务中运行,这样当应用程序被置于屏幕后台运行时(如此时打开了其他应用程序),仍然能在后台接收到服务器发送的消息并通知用户处理[4]。
Android 客户端设计的通信服务组件CommunicationService 继承自Android 系统的 Service 组件, 并重写它的 OnBind, OnCreate,OnStart 和OnDestroy 等方法。
(1) OnBind:将当前服务器实例返回给绑定服务的组件, 如Application。
(2) OnCreate:读取应用程序上下文,并广播消息告知服务已经启动。
(3) OnStart:判断客户端是否通过身份认证, 若是, 则在尚未连接的条件下与通信服务器进行连接,此处使用WebSocket客户端对象来与系统通信服务器建立连接, 实现消息的发送和接收, 在 WebSocketClient.Handler实例中重写onMessage方法以实现对接收到的消息进行处理。当WebSocket客户端接收到来自服务器的消息时,首先通过消息模型MessageModel的parse方法将文本消息转换为消息对象, 并根据消息类型调用消息处理模块MessageHandle的对应方法对消息进行进一步处理,同时传入OnMessageListener接口, 将消息模型传递给UI层进行必要的处理。
(4) OnDestroy:关闭与通信服务器的链接,释放资源。
3.2 Android客户端效果图
Android 客户端设计效果图如图 3 所示。
4 结 语
本平台使用Netty+WebSocket 技术解决了移动设备与后台服务器双向通讯的问题,后台可以随时向用户推送消息,以保证前后台状态统一,在传统的HTTP 协议中,这是很难实现的,下一步工作将在数据格式上进行进一步细化和分类,将分类和实时推送做到最优。