使用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);
}
}
}}
}


}

阅读全文
2 0
原创粉丝点击