本文旨在用vert.x与echarts开发一个实时环境监控demo。
vert.x参看http://vertx.io
ehcars参看http://echarts.baidu.com/index.html
整个业务流程比较简单,就是页面通过sockJs与后端的web服务器通讯,然后后端服务器实时推送数据到页面。
页面代码如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript" src="/js/jquery-easyui-1.5.2/jquery.min.js"></script> <script type="text/javascript" src="/js/sockjs.min.js"></script> <script type="text/javascript" src="/js/vertx-eventbus.min.js"></script> <script type="text/javascript" src="/js/baidu/echarts-all.js"></script> </head> <body> <div><b>环境实时监控:</b></div> <br> <table width="800"> <tr> <td><font color="blue">温度</font></td> <td><font color="blue">湿度</font></td> <td><font color="blue">CO2</font></td> <td><font color="blue">NH3</font></td> </tr> <tr> <td><div id="T"></div></td> <td><div id="H"></div></td> <td><div id="CO2"></div></td> <td><div id="NH3"></div></td> </tr> </table> <br> <table> <tr> <td><div id="T_chart" style="width: 250px;height:250px;"></div></td> <td><div id="T_chart_line" style="width: 500px;height:250px;"></div></td> <td><div id="H_chart" style="width: 250px;height:250px;"></div></td> <td><div id="H_chart_line" style="width: 500px;height:250px;"></div></td> </tr> <tr> <td><div id="CO2_chart" style="width: 250px;height:250px;"></div></td> <td><div id="CO2_chart_line" style="width: 500px;height:250px;"></div></td> <td><div id="NH3_chart" style="width: 250px;height:250px;"></div></td> <td><div id="NH3_chart_line" style="width: 500px;height:250px;"></div></td> </tr> </table> <script> // 仪表盘------------------------------------------------------------------- var myChart_T = echarts.init(document.getElementById("T_chart")); var option_T = { series : [ { name:'温度', type:'gauge', detail : {formatter:'{value}℃'}, data:[{value: 50, name: '温度'}], min:0, max:50, axisLine:{ show: true, //给每一段指定颜色(本例中温度分低,适宜,高三段),格式:百分比,颜色。 lineStyle: { color: [ [0.3, '#228b22'], [0.7, '#48b'], [1, '#ff4500'] ], width: 20 } }, splitLine:{ length :20 } } ] }; myChart_T.setOption(option_T); var myChart_H = echarts.init(document.getElementById("H_chart")); var option_H = { series : [ { name:'湿度', type:'gauge', detail : {formatter:'{value}%'}, data:[{value: 50, name: '湿度'}], axisLine:{ show: true, lineStyle: { color: [ [0.4, '#228b22'], [0.75, '#48b'], [1, '#ff4500'] ], width: 20 } }, splitLine:{ length :20 } } ] }; myChart_H.setOption(option_H); var myChart_CO2 = echarts.init(document.getElementById("CO2_chart")); var option_CO2 = { series : [ { name:'CO2', type:'gauge', detail : {formatter:'{value}%'}, data:[{value: 0.05, name: 'CO2'}], min:0, max:0.15, splitNumber:5, axisLine:{ show: true, lineStyle: { color: [ [0.33, '#228b22'], [0.66, '#48b'], [1, '#ff4500'] ], width: 20 } }, splitLine:{ length :20 } } ] }; myChart_CO2.setOption(option_CO2); var myChart_NH3 = echarts.init(document.getElementById("NH3_chart")); var option_NH3 = { series : [ { name:'NH3', type:'gauge', detail : {formatter:'{value}%'}, data:[{value: 0.05, name: 'NH3'}], min:0, max:0.005, splitNumber:10, axisLine:{ show: true, lineStyle: { color: [ [0.9, '#48b'], [1, '#ff4500'] ], width: 20 } }, splitLine:{ length :20 } } ] }; myChart_NH3.setOption(option_NH3); var count = 0; var date = []; // 折线图---------------------------------------------------------------------------------- var myChart_T_line = echarts.init(document.getElementById("T_chart_line")); var data_T = []; var option_T_line = { xAxis: { type: 'category', boundaryGap: false, data: date }, yAxis: { min:0, max:50, type: 'value' }, series: [ { name:'meanRate', type:'line', smooth:true, areaStyle: { normal: {} }, data: data_T } ] }; myChart_T_line.setOption(option_T_line); myChart_T_line.hideLoading(); var myChart_H_line = echarts.init(document.getElementById("H_chart_line")); var data_H = []; var option_H_line = { xAxis: { type: 'category', boundaryGap: false, data: date }, yAxis: { min:0, max:100, type: 'value' }, series: [ { name:'meanRate', type:'line', smooth:true, areaStyle: { normal: {} }, data: data_H } ] }; myChart_H_line.setOption(option_H_line); myChart_H_line.hideLoading(); var myChart_CO2_line = echarts.init(document.getElementById("CO2_chart_line")); var data_CO2 = []; var option_CO2_line = { xAxis: { type: 'category', boundaryGap: false, data: date }, yAxis: { min:0, max:0.20, type: 'value' }, series: [ { name:'meanRate', type:'line', smooth:true, areaStyle: { normal: {} }, data: data_CO2 } ] }; myChart_CO2_line.setOption(option_CO2_line); myChart_CO2_line.hideLoading(); var myChart_NH3_line = echarts.init(document.getElementById("NH3_chart_line")); var data_NH3 = []; var option_NH3_line = { xAxis: { type: 'category', boundaryGap: false, data: date }, yAxis: { min:0, max:0.007, type: 'value' }, series: [ { name:'meanRate', type:'line', smooth:true, areaStyle: { normal: {} }, data: data_NH3 } ] }; myChart_NH3_line.setOption(option_NH3_line); myChart_NH3_line.hideLoading(); // webSocket------------------------------------------------------------------------ var eb = new EventBus("/eventbus/"); eb.onopen = function() { eb.registerHandler("chartServer.to.client", function(err, msg) { $('#T').text(msg.body.T + "\n"); $('#H').text(msg.body.H + "\n"); $('#CO2').text(msg.body.CO2 + "\n"); $('#NH3').text(msg.body.NH3 + "\n"); option_T.series[0].data[0].value = msg.body.T; myChart_T.setOption(option_T, true); option_H.series[0].data[0].value = msg.body.H; myChart_H.setOption(option_H, true); option_CO2.series[0].data[0].value = msg.body.CO2; myChart_CO2.setOption(option_CO2, true); option_NH3.series[0].data[0].value = msg.body.NH3; myChart_NH3.setOption(option_NH3, true); date.push(msg.body.time); count = count + 1; if(count > 100){ date.shift(); data_T.shift(); data_H.shift(); data_CO2.shift(); data_NH3.shift(); } data_T.push(msg.body.T); data_H.push(msg.body.H); data_CO2.push(msg.body.CO2); data_NH3.push(msg.body.NH3); myChart_T_line.setOption(option_T_line, true); myChart_H_line.setOption(option_H_line, true); myChart_CO2_line.setOption(option_CO2_line, true); myChart_NH3_line.setOption(option_NH3_line, true); }); }; </script> </body> </html>
后台代码如下:
package com.wof.realtimesca.chart; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.GregorianCalendar; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.handler.sockjs.BridgeEventType; import io.vertx.ext.web.handler.sockjs.BridgeOptions; import io.vertx.ext.web.handler.sockjs.PermittedOptions; import io.vertx.rxjava.core.AbstractVerticle; import io.vertx.rxjava.core.eventbus.EventBus; import io.vertx.rxjava.core.eventbus.Message; import io.vertx.rxjava.core.eventbus.MessageConsumer; import io.vertx.rxjava.ext.web.Router; import io.vertx.rxjava.ext.web.handler.StaticHandler; import io.vertx.rxjava.ext.web.handler.sockjs.SockJSHandler; import rx.Observable; import rx.Subscription; public class ChartVerticle extends AbstractVerticle { private static final Logger logger = LoggerFactory.getLogger(ChartVerticle.class); public void start() throws Exception { // 路由器 Router router = Router.router(vertx); // 事件总线 BridgeOptions bridgeOptions = new BridgeOptions() .addInboundPermitted(new PermittedOptions().setAddress("tcpServer.to.chartServer")) .addOutboundPermitted(new PermittedOptions().setAddress("chartServer.to.client")); SockJSHandler sockJSHandler = SockJSHandler.create(vertx).bridge(bridgeOptions, event -> { if (event.type() == BridgeEventType.SOCKET_CREATED) { logger.info("a socket creatae."); } else if (event.type() == BridgeEventType.SOCKET_CLOSED){ logger.info("a socket closed."); } event.complete(true); }); sockJSHandler.socketHandler(sockJSSocket -> { sockJSSocket.exceptionHandler(handler -> { logger.error(handler.getCause().getMessage()); }); }); router.route("/eventbus/*").handler(sockJSHandler); router.route().handler(StaticHandler.create());//这种没有任何前缀的静态资源handler一定要放到sockJSHandler后面;否则,jsSocket无法与后台通讯。 EventBus eventBus = vertx.eventBus(); MessageConsumer<String> consumer = eventBus.consumer("tcpServer.to.chartServer"); Observable<Message<String>> observable = consumer.toObservable(); //message结构(json): {"type":"rec","address":"char.to.client.push","body":"welcome!"} Subscription sub = observable.subscribe(msg -> { eventBus.publish("chartServer.to.client", msg.body()); }); // http server vertx.createHttpServer().requestHandler(router::accept).listen(8090); // 模拟传感器发送数据到服务器 SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); vertx.setPeriodic(500, t -> { JsonObject jsonData = new JsonObject(); String date = sdf.format(GregorianCalendar.getInstance().getTime()); jsonData.put("time", date); String data = getDataValue(28, 30, 0, 1);//温度 jsonData.put("T", data); data = getDataValue(70, 75, 0, 1);//湿度 jsonData.put("H", data); data = getDataValue(5, 10, 2, 2);//CO2 0.05—0.1% jsonData.put("CO2", data); data = getDataValue(1, 4, 3, 4);//NH3 < 0.004﹪ jsonData.put("NH3", data); vertx.eventBus().publish("tcpServer.to.chartServer", jsonData); }); } /** * 产生随机小数 * * @param min * @param max * @param count 小数位数 * @param zeroCount 需要保留的小数位数 * @return */ private String getDataValue(int min, int max, int count, int zeroCount){ double d = (Math.random() * (max - min + 1) + min); for(int i = 1; i <= count ; i++){ d /= 10; } String zero = "0."; if(zeroCount < 1) zero = "0.0"; else { for(int i = 1; i <= zeroCount; i++){ zero += "0"; } } DecimalFormat Dformat = new DecimalFormat(zero); String val = Dformat.format(d); return val; } }
效果图:
相关推荐
Vert.x是事件驱动的,其处理请求的高性能也是基于其事件机制。Vert.x的事件机制中有几个非常重要的概念:Event Loop、Event Loop Vertical、Worker Vertical、Event Bus、Vert.x Module。 Event Loop:即事件循环,...
Vert.x 是一个轻量级、高性能的反应式应用开发框架,适用于 Java 和其他多种语言。它的核心组件小巧且灵活,允许开发者只使用需要的部分,并能无缝嵌入到现有的应用程序中,无需按照特定的架构模式进行改造。Vert.x ...
将Vert.x与Spring Boot结合,我们可以利用Spring Boot的便捷配置和管理特性,以及Vert.x的高性能事件驱动架构,实现高效的MQTT服务器。 下面是一些关键步骤和技术点: 1. **设置项目结构**:创建一个标准的Spring ...
在阅读《vert.x中文 PDF 下载》这本书时,你会了解到如何配置和启动vert.x环境,创建和部署Verticle,使用事件总线进行通信,以及如何利用vert.x提供的各种组件(如HTTP服务器、TCP服务器、WebSocket)构建网络应用...
- vert.x 适用于微服务架构、实时大数据处理、物联网(IoT)应用、高并发的Web服务以及任何需要高度并发和低延迟的场景。 总结来说,vert.x-2.1.2 是一个基于Java和NIO的高效应用框架,它为开发人员提供了构建...
《Vert.x应用开发实例教程》旨在为Vert.x的初学者和大中专院校学生提供易于入门,全面了解和掌握Vert.x框架技术和应用的教材和辅导资料,为使用Vert.x开发实时应用和企业级应用打下良好的基础。
标题中的“基于Vert.x(java)开发的API网关”指的是使用Vert.x框架构建的应用程序,该应用程序主要功能是作为API网关。API网关是一种架构模式,它充当客户端(如Web应用、移动应用或IoT设备)与后端服务之间的单一...
【标签】"Node.Js vertx" 表明这是一个关于比较和使用Node.js与Vert.x的讨论。Node.js以其高效的异步非阻塞I/O和丰富的生态系统而闻名,适合构建Web服务器和实时应用。Vert.x则提供了一个更为通用的工具集,不仅包含...
Vert.x的核心设计理念是提供一个轻量级的运行时环境,支持多种编程语言,包括Java、JavaScript、Ruby、Groovy等,使得开发者可以灵活地选择适合项目需求的语言。 【描述】"源码下载 博文链接:...
在使用Vert.x框架开发分布式应用时,为了更好地控制和优化应用性能,开发者通常需要通过`VertxOptions`类来定制化配置Vert.x实例。`VertxOptions`是用于创建`Vertx`实例时的一个配置对象,它提供了丰富的配置选项来...
Vert.x 是一个轻量级、高性能且反应式的应用开发框架,主要用于构建现代的、事件驱动的、非阻塞式的Java应用程序。它支持多种编程语言,包括Java、JavaScript、Ruby、Groovy和 Kotlin,提供了一个统一的API来处理...
2. **多语言支持**:虽然主要用Java编写,但Vert.x 提供了API接口,支持其他如JavaScript、Ruby、Groovy、Ceylon等多种语言,这使得开发人员可以选择他们最熟悉的语言进行开发。 3. **模块化系统**:Vert.x 允许...
#### 四、Vert.x与Netty的线程模型对比 - **Netty**:Netty使用两个线程池:Boss Group和Worker Group。Boss Group负责接收新的连接,而Worker Group则处理连接上的I/O操作。 - **Vert.x**:虽然Netty也是Vert.x的...
- **开发环境:** 实验建议使用个人笔记本电脑,并安装 Windows、Mac OS 或 Linux 操作系统。此外,还需要安装 Docker,尽管 Vert.x 并不依赖 Docker,但它有助于模拟分布式系统环境。 - **实践目标:** 通过构建...
vert.x是内存占用极小的快速开发框架,springboot模版项目
Vert.X-generator是基于javafx8开发的图形界面Vert.x代码生成器,使用 Apache FreeMarker 作为代码文件的模板,用户可以一键将数据库中的表生成为任意风格的.java代码文件(比如经典的三层模型);该工具支持所有实现JDBC...
Java API 版本的Vert.x Core 手册是关于Vert.x框架的重要参考资料,该框架是用Java编写的高度可扩展的事件驱动平台,适用于构建现代的、反应式的微服务和网络应用。 Vert.x Core是其核心组件,提供了低级别的API,...
### Vert.x for Java 开发者知识点详解 #### 一、简介 **Vert.x** 是一个高性能的异步框架...以上是关于如何使用Vert.x进行Java异步开发的基础知识点。通过学习这些内容,开发者可以构建出高性能、可扩展的应用程序。
vertx-kue, Vert.x Blueprint项目 Vert.x Kue,这是由 Vert.x 支持的优先级任务队列 Vert.x Kue Vert.x Kue 是用 Vert.x 开发的优先级任务队列,并以的Redis支持。 它是 automattic/kue的Vert.x 实现版本。这个蓝图...