使用websocket和highcharts实现动态图标展示
来源:互联网 发布:淘宝代销不是长久之计 编辑:程序博客网 时间:2024/05/17 07:30
利用阿里云物联网套件做一个物联网平台的demo,摸着石头过河.
到了这一步,需要在页面实施监控设备上报的数据,
之前用ajax结合highcharts试了下,前台要定时请求,比较被动,上报时间不一定,想实现上报之后马上推送,用了websocket,
开始是直接消费阿里云的队列,各种问题,后来在本地搭建activemq配合使用,
一开始直接在onmessage里面写消费消息,导致开多个窗口,多个设备,多个属性都有问题,
后来是主动去推,有多少session就推多少
2017年11月20日11:16:21核心是map.get(device_name).getBasicRemote().sendText(msg);session在map里面放着
private static List<Map<String, Session>> sessionlist = (new CopyOnWriteArrayList<Map<String, Session>>());
jsp---
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%-- 使用jsp的隐式注释; --%><!DOCTYPE html>
<html>
<head id="Head1">
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>longshine-iot-web平台</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<%-- 避免IE使用兼容模式 --%>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<%@include file="/common/jsp/common.jsp" %>
<link rel="stylesheet" type="text/css" href="${ctx }/common/css/base/core.css" />
<link rel="stylesheet" type="text/css" href="${ctx }/common/css/base/basetable.css" />
<script type="text/javascript" src='${ctx }/common/js/jquery-2.1.4.min.js'> </script>
<script src="${ctx }/common/js/Highcharts-5.0.14/code/highcharts.js"></script>
<script src="${ctx }/common/js/Highcharts-5.0.14/code/modules/exporting.js"></script>
<script type="text/javascript" src='${ctx }/iotweb/device_charts_dynamic.js'> </script>
<script type="text/javascript">
var device_name = "${param.device_name}";
var type = "${param.type}";
var ms = "${param.ms}";
</script>
</head>
<body>
<div id="container" style="width: 100%;height: 100%">
</div>
</body>
</html>
js---
$(function() {
// 初始化图表
startCharts();
// 初始化websocket
startWebsocket();
});
Highcharts.setOptions({
global : {
useUTC : false
}
});
var chart2 = null;
function startCharts() {
chart2 = new Highcharts.Chart({
chart : {
type : 'spline',
renderTo : 'container',
animation : Highcharts.svg, // don't animate in old IE
marginRight : 10
},
title : {
text : '设备上报实时数据-'+ms
},
xAxis : {
type : 'datetime',
tickPixelInterval : 150
},
yAxis : {
title : {
text : ms
},
plotLines : [ {
value : 0,
width : 1,
color : '#808080'
} ]
},
tooltip : {
formatter : function() {
return '<b>' + this.series.name + '</b><br/>'
+ Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x)
+ '<br/>值:' + Highcharts.numberFormat(this.y, 2);
}
},
legend : {
enabled : false
},
exporting : {
enabled : false
},
series : [ {
name : ms,
data : (function() {
// generate an array of random data
var data = [], time = (new Date()).getTime(), i;
for (i = -14; i <= 0; i += 1) {
data.push({
x : time + i * 1000,
y : !+14
});
}
return data;
}())
} ]
}, function(c) {
activeLastPointToolip(c)
});
}
function activeLastPointToolip(chart) {
var points = chart.series[0].points;
chart.tooltip.refresh(points[points.length - 1]);
}
//websocket取数据;
var socket = null;
function startWebsocket(){
// 实现化WebSocket对象,指定要连接的服务器地址与端口
socket = new WebSocket("ws://localhost:8080/iotweb/ws/currentdevicews");
// 打开事件
socket.onopen = function() {
console.log("Socket 已打开");
socket.send('{"device_name":"'+device_name+'","type":"'+type+'"}');
};
// 获得消息事件
socket.onmessage = function(msg) {
onMessage(msg);
};
// 关闭事件
socket.onclose = function() {
console.log("Socket已关闭");
};
// 发生了错误事件
socket.onerror = function() {
console.log("Socket发生了错误");
}
}
window.onbeforeunload = function() {
closeWebSocket();
}
function closeWebSocket() {
socket.send("killed");
//socket.close();
}
function onMessage(event) {
var kk = JSON.parse(event.data);
var y_value = kk[type];
var x_value = kk.timestamp;
//var y_value = kk.x;
var series = chart2.series[0];
//var x = (new Date()).getTime(), // current time
//y = parseInt(y_value);
var x = Number(x_value), // current time
y = Number(y_value);
console.log(x);
console.log(y);
series.addPoint([ x, y ], true, true);
activeLastPointToolip(chart2);
}
后台代码---
package com.longshine.iot.demo.ws;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import net.sf.json.JSONObject;
@Component
@ServerEndpoint("/ws/currentdevicews")
public class CurrentDeviceWs {
// private static Logger log = Logger.getLogger(CurrentDeviceWs.class);
// 存储链接的容器
// private static List<Map<String, Session>> sessionlist = Collections.synchronizedList(new ArrayList<Map<String, Session>>());
private static List<Map<String, Session>> sessionlist = (new CopyOnWriteArrayList<Map<String, Session>>());
// 连接打开时执行
@OnOpen
public void onOpen(Session session) {
System.out.println("创建新连接:Connected ... " + session.getId());
// map.put(session.getId(), session);
}
// 收到消息时执行
@OnMessage
public void onMessage(String message, Session session) throws InterruptedException, IOException {
if (StringUtils.isNotBlank(message)&&!"killed".equals(message)) {
System.out.println("接收到信息:" + message + ",from session:" + session.getId());
JSONObject js = JSONObject.fromObject(message);
String device_name = js.get("device_name").toString();
// String type = js.get("type").toString();
// System.out.println("devicename:" + device_name);
Map<String, Session> map = new HashMap<String, Session>();
map.put(device_name, session);
sessionlist.add(map);
System.out.println("sessionlist加入session:" + session.getId()+"当前sessionlist.size"+sessionlist.size());
/* for (int i = 0; i < 2; i++) {
Thread.sleep(1000);
sendMessageToWeb("{\"devicename\":\"device_01\",\"djgl\":\""+i+"\",\"fjgl\":\"347.4\",\"lmb_gl\":\"314.7\",\"lmb_ll\":\"302.3\",\"lmb_yc\":\"19.1\",\"lmb_yxdl\":\"286.4\",\"lmsll\":\"317.3\",\"lqsll\":\"141.0\",\"nhl\":\"348.9\",\"timestamp\":\""+System.currentTimeMillis()+"\",\"zll\":\"479.2\"}");
}*/
}else{
session.close();
}
}
// 连接关闭时执行
@OnClose
public void onClose(Session session, CloseReason closeReason) {
System.out.println(String.format("Session %s closed because of %s", session.getId(), closeReason));
for (Map<String, Session> map : sessionlist) {
for (String device_name : map.keySet()) {
if (map.get(device_name).getId().equals(session.getId())) {
sessionlist.remove(map);
System.out.println("sessionlist移除session:" + session.getId()+"当前sessionlist.size"+sessionlist.size());
}
}
}
}
// 连接错误时执行
@OnError
public void onError(Throwable t) {
t.printStackTrace();
}
public static void sendMessageToWeb(String msg) {
JSONObject jj = JSONObject.fromObject(msg);
String devicename=jj.getString("devicename");
System.out.println("接收到的消息为:"+msg);
if(sessionlist!=null && !sessionlist.isEmpty()){
for (Map<String, Session> map : sessionlist) {
for (String device_name : map.keySet()) {
if (devicename.equals(device_name)) {
try {
map.get(device_name).getBasicRemote().sendText(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("发送到session:" + map.get(device_name).getId()+",device_name:"+device_name);
}
}
}}
}
}
- 使用websocket和highcharts实现动态图标展示
- 使用Highcharts实现曲线图和饼型图的展示
- 使用HighCharts实现实时数据展示
- 使用HighCharts实现实时数据展示
- 使用HighCharts实现实时数据展示
- web worker+highcharts动态实现可视化数据展示
- 使用highcharts来实现报表的展示以及打印和导出功能
- Highcharts柱状图动态数据展示
- 家庭财务管理系统实战6-使用Highcharts插件动态展示支出趋向图饼图(pie)和线图(line)
- HighCharts 随机数动态曲线展示(动态数据实时展示)
- highcharts折线图动态数据展示
- Highcharts动态实现柱形图
- Highcharts动态实现柱形图
- Android客户端使用highcharts进行图表展示
- Html5和WebSocket----使用WebSocket实现即时通信
- highcharts 实现动态加载多个饼图
- highcharts示例和使用
- websocket+d3.JS实现图标实时更新
- flask django 上传文件
- Xcode8.1 bundle format unrecognized, invalid, or unsuitable
- linux常用小技巧
- 成功集成个推后,点击推送直接跳入app指定页面
- 初步认识restful接口
- 使用websocket和highcharts实现动态图标展示
- 快速排序Java实现
- 修改CSpreadSheet commit函数,让其插入新行时不再重复删除 创建 写数据
- 继承 多态 接口 抽象类 内部类
- 【真题】京东2017校招编程题 进制均值
- Java常用类——Date类、SimpleDateFormate类
- bootstarup栅格系统
- java递归-小鸡吃米问题
- 【Android前端】Bing每日图片列表应用制作记录——1.从零开始