使用websocket和highcharts实现动态图标展示

原创 2017年08月11日 16:41: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);
}
}
}}
}


}

版权声明:本文为博主原创文章,未经博主允许不得转载。

使用HighCharts实现实时数据展示

在众多的工业控制系统领域常常会实时采集现场的温度、压力、扭矩等数据,这些数据对于监控人员进行现场态势感知、进行未来趋势预测具有重大指导价值。工程控制人员如果只是阅读海量的数据报表,对于现场整个态势的掌...
  • gzh0222
  • gzh0222
  • 2014年04月26日 16:59
  • 16519

使用WebSocket实现图文直播功能

WebSocket,简单理解就是H5自带的一套Socket API,用它来实现客户端与服务端的长连接。使用案例: 实现一个活动的实时报道,也就是图文直播功能 首先来看下项目的结构,很简单,就两个类 M...

HTML5-WebSocket实现对服务器CPU实时监控

由于WebSocket允许保持长连接,因此当建立连接后服务器可以主动地向Client发送相关信息.下面通过服务端获取当前CPU的使用情况主动发送给网页,让网页实时显示CPU使用情况的曲线图.该事例的主...

WebSocket 实时更新mysql数据到页面

使用websocket的初衷是,要实时更新mysql中的报警信息到web页面显示 没怎么碰过web,代码写的是真烂,不过也算是功能实现了,放在这里也是鞭策自己,web也要多下些功夫准备工作先看看my...
  • Nougats
  • Nougats
  • 2017年07月18日 15:16
  • 2242

Linux 指定运行时动态库路径[-rpath]

众所周知, Linux 动态库的默认搜索路径是 /lib 和 /usr/lib 。动态库被创建后,一般都复制到这两个目录中。当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两...

链接选项rpath,容易被忽略的一个功能

问题来源 最近在做一个项目的客户端的SDK,实现为一个动态链接库,其依赖于其他的若干个动态库文件。那么在利用SDK开发应用程序的时候,编译的时候除了链接SDK库本身,还得链接SDK库所依赖的库,这样编...

家庭财务管理系统实战6-使用Highcharts插件动态展示支出趋向图饼图(pie)和线图(line)

本篇用highcharts控件展示支出去向图和支出趋势图。 研究了一阵儿,控件挺好用的,而且效果也不错。 本篇实现家庭财务管理系统首页的展示,参考了一下“随手记”,打算在首页展示以下内容: 1.收支表...

图标控件Highcharts使用指南

一、前言(Preface) Highcharts是一个非常流行,界面美观的纯Javascript图表库。它主要包括两个部分:Highcharts和Highstock。 Highchar...

websocket+d3.JS实现图标实时更新

服务端代码://var connection=require('./config.js').connection; // //connection.connect(); // //console.lo...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用websocket和highcharts实现动态图标展示
举报原因:
原因补充:

(最多只允许输入30个字)