Commit d70bd13b by lixinming

no message

parent 10c10382
<config> <config>
<portConfig>30001</portConfig> <port>30001</port>
<socketPortConfig>30002</socketPortConfig> <socketPort>30002</socketPort>
<rightView>http://10.51.50.136:8090/sql/execute</rightView> <rightView>http://10.51.50.136:8090/sql/execute</rightView>
<leftView> <leftView>
<cloudResource>http://10.51.50.140:8080/api/static/PrivateCloudUsageStatics</cloudResource> <cloudResource>http://10.51.50.140:8080/api/static/PrivateCloudUsageStatics</cloudResource>
...@@ -14,11 +14,12 @@ ...@@ -14,11 +14,12 @@
<broken>3</broken> <broken>3</broken>
<token>09a98bc555474e058ef90b6cc6e23638</token> <token>09a98bc555474e058ef90b6cc6e23638</token>
</mapView> </mapView>
<imagePath>192.168.0.100</imagePath> <imagePath>192.168.0.105</imagePath>
<mapCenter> <mapCenter>
<lng>121.183574</lng> <lng>121.183574</lng>
<lat>31.291126</lat> <lat>31.291126</lat>
</mapCenter> </mapCenter>
<zoom>14</zoom> <zoom>14</zoom>
<surveillanceVideo>http://10.51.50.53:8278/live/13060200882000000001@31011402601318800184@34020000001320000001.m3u8?vhost=bduv0utmss4c3nzidjn.a.e-web.com.cn</surveillanceVideo> <surveillanceVideo>http://10.51.50.53:8278/live/13060200882000000001@31011402601318800184@34020000001320000001.m3u8?vhost=bduv0utmss4c3nzidjn.a.e-web.com.cn</surveillanceVideo>
<wsPath>ws://10.51.50.136:8090/ws/v1</wsPath>
</config> </config>
import moment = require("moment");
import { getChartOutData, getKeyValueNumberOutData, getListOutData } from "../../cal/out"; import { getChartOutData, getKeyValueNumberOutData, getListOutData } from "../../cal/out";
import { separateDataAndUint } from "../../cal/privateTools"; import { separateDataAndUint } from "../../cal/privateTools";
import { getImageIp, latConfig, lngConfig, port, surveillanceVideoConfig, zoomConfig } from "../../config/serverConfig"; import { appConfig, getImageIp, systemConfig} from "../../config/serverConfig";
import { getHardware } from "../../data/interface/hardwareData"; import { getHardware } from "../../data/interface/hardwareData";
import { getCsgkData, getDetachmentRatio, getTestAnalysis, getTestTotalTime } from "../../data/interface/interfaceService"; import { getCsgkData, getDetachmentRatio, getTestAnalysis, getTestTotalTime } from "../../data/interface/interfaceService";
import { getMap } from "../../data/interface/mapInterfaceData"; import { getMap } from "../../data/interface/mapInterfaceData";
...@@ -25,16 +26,27 @@ export async function getYZY(req, res) { ...@@ -25,16 +26,27 @@ export async function getYZY(req, res) {
} }
//测试概况 //测试概况
let csgkQueue = {};
let csgkQueueTime = "";
export async function getCSGK(req, res) { export async function getCSGK(req, res) {
let ret:any = {}; let ret:any = {};
let today = moment().format("YYYYMMDD");
if (today == csgkQueueTime) {
let 今日数据data = {"在线车辆数":`${getOnlieCarCount()}辆`};
csgkQueue["api2"] = getKeyValueNumberOutData("今日数据", 今日数据data);
res.send(csgkQueue);
return;
}
csgkQueueTime = today;
let {测试牌照分布data, result, 今日数据, 今日测试, 今日功能测试} = await getCsgkData(); let {测试牌照分布data, result, 今日数据, 今日测试, 今日功能测试} = await getCsgkData();
let 基础数据Info = []; let 基础数据Info = [];
result.forEach((info, index) => { result.forEach((info, index) => {
let {key, value} = info; let {key, value} = info;
let {dataNum, dataUnit} = separateDataAndUint(value); let {dataNum, dataUnit} = separateDataAndUint(value);
基础数据Info.push({key, value:dataNum, unit:dataUnit, icon:`http://${getImageIp()}:${port}/csgk/${index+1}.png`}); 基础数据Info.push({key, value:dataNum, unit:dataUnit, icon:`http://${getImageIp()}:${systemConfig.port}/csgk/${index+1}.png`});
}); });
ret["api1"] = ({title:"基础数据", dataList: 基础数据Info}); ret["api1"] = ({title:"基础数据", dataList: 基础数据Info});
...@@ -46,16 +58,63 @@ export async function getCSGK(req, res) { ...@@ -46,16 +58,63 @@ export async function getCSGK(req, res) {
ret["api5"] = getKeyValueNumberOutData("测试牌照分布", 测试牌照分布data); ret["api5"] = getKeyValueNumberOutData("测试牌照分布", 测试牌照分布data);
let 路侧监控视频data = {"src": surveillanceVideoConfig, "type": 'application/x-mpegURL'}; let 路侧监控视频data = {"src": appConfig.surveillanceVideo, "type": 'application/x-mpegURL'};
ret["api6"] = ({title:"路侧监控视频", dataList: 路侧监控视频data}); ret["api6"] = ({title:"路侧监控视频", dataList: 路侧监控视频data});
csgkQueue = JSON.parse(JSON.stringify(ret));
res.send(ret); res.send(ret);
} }
//测试分析 //测试分析
let csfxQueue = {};
let csfxQueueTime = "";
export async function getCSFX(req, res) { export async function getCSFX(req, res) {
let ret:any = {}; let ret:any = {};
let today = moment().format("YYYYMMDD");
if (today == csfxQueueTime) {
res.send(csfxQueue);
return;
}
csfxQueueTime = today;
getDetachmentRatio().then((data) => {
let 企业脱离自动驾驶比率data = data;
企业脱离自动驾驶比率data.forEach( item => {
let frequency = separateDataAndUint(item.次数).dataNum;
let kilometer = separateDataAndUint(item.里程).dataNum;
let ratio = Math.ceil(frequency/kilometer*100);
item["比率"] = ratio;
})
企业脱离自动驾驶比率data.sort((a, b) => {
return b.比率 - a.比率;
})
let 企业脱离自动驾驶比率Top10 = 企业脱离自动驾驶比率data.slice(0, 10);
let 企业名称data = [];
let 次数data = [];
let 里程data = [];
let 比率data = [];
企业脱离自动驾驶比率Top10.forEach( info => {
let {企业名称, 次数, 里程, 比率} = info;
企业名称data.push(企业名称);
次数data.push(次数);
里程data.push(里程);
比率data.push(比率 + "%");
})
let 企业测试自动驾驶比率Info = [
{key:"企业名称", values: 企业名称data},
{key:"次数", values: 次数data},
{key:"里程", values: 里程data},
{key:"比率", values: 比率data},
];
ret["api5"] = getListOutData("企业脱离自动驾驶比率", 企业测试自动驾驶比率Info);
});
let {testMileage, functionTestMileage, testMileageEnterprise, functionTestMileageEnterprise} = await getTestAnalysis(); let {testMileage, functionTestMileage, testMileageEnterprise, functionTestMileageEnterprise} = await getTestAnalysis();
let 月度测试里程分布data = {测试: {unit:'km', dataInfo: testMileage}, 功能测试: {unit:'km', dataInfo: functionTestMileage}}; let 月度测试里程分布data = {测试: {unit:'km', dataInfo: testMileage}, 功能测试: {unit:'km', dataInfo: functionTestMileage}};
ret["api1"] = getChartOutData("月度测试里程分布", 月度测试里程分布data); ret["api1"] = getChartOutData("月度测试里程分布", 月度测试里程分布data);
...@@ -73,41 +132,7 @@ export async function getCSFX(req, res) { ...@@ -73,41 +132,7 @@ export async function getCSFX(req, res) {
let 企业测试时长分布data = {测试: {unit:'h', dataInfo: testTimeEnterprise}, 功能测试: {unit:'h', dataInfo: functionTestTimeEnterprise}}; let 企业测试时长分布data = {测试: {unit:'h', dataInfo: testTimeEnterprise}, 功能测试: {unit:'h', dataInfo: functionTestTimeEnterprise}};
ret["api4"] = getChartOutData("企业测试时长分布", 企业测试时长分布data); ret["api4"] = getChartOutData("企业测试时长分布", 企业测试时长分布data);
let 企业脱离自动驾驶比率data = await getDetachmentRatio(); csfxQueue = JSON.parse(JSON.stringify(ret));
企业脱离自动驾驶比率data.forEach( item => {
let frequency = separateDataAndUint(item.次数).dataNum;
let kilometer = separateDataAndUint(item.里程).dataNum;
let ratio = Math.ceil(frequency/kilometer*100);
item["比率"] = ratio;
})
企业脱离自动驾驶比率data.sort((a, b) => {
return b.比率 - a.比率;
})
let 企业脱离自动驾驶比率Top10 = 企业脱离自动驾驶比率data.slice(0, 10);
let 企业名称data = [];
let 次数data = [];
let 里程data = [];
let 比率data = [];
企业脱离自动驾驶比率Top10.forEach( info => {
let {企业名称, 次数, 里程, 比率} = info;
企业名称data.push(企业名称);
次数data.push(次数);
里程data.push(里程);
比率data.push(比率 + "%");
})
let 企业测试自动驾驶比率Info = [
{key:"企业名称", values: 企业名称data},
{key:"次数", values: 次数data},
{key:"里程", values: 里程data},
{key:"比率", values: 比率data},
];
ret["api5"] = getListOutData("企业脱离自动驾驶比率", 企业测试自动驾驶比率Info);
res.send(ret); res.send(ret);
} }
...@@ -151,9 +176,9 @@ export async function mapData(req, res) { ...@@ -151,9 +176,9 @@ export async function mapData(req, res) {
} }
] ]
ret["mapCenter"] = {lng: lngConfig, lat: latConfig}; ret["mapCenter"] = {lng: appConfig.lng, lat: appConfig.lat};
ret["zoom"] = {key: "缩放比例", value: zoomConfig}; ret["zoom"] = {key: "缩放比例", value: appConfig.zoom};
res.send(ret); res.send(ret);
} }
\ No newline at end of file
import { getDpData } from "../../data/interface/wsData";
import { Socket } from "../../net/socket_server"; import { Socket } from "../../net/socket_server";
import { logError } from "../../util/log";
//连接池 //连接池
let connectionPool = {}; let connectionPool = {};
//数据池
let dataQueue = [];
//广播消息 //广播消息
export async function sendMsg(data) { export function broadcastMsg(data) {
dataQueue.push(data);
for (let key in connectionPool) { for (let key in connectionPool) {
let result = {code:200, success:true, data} let result = {code:200, success:true, data};
try { try {
connectionPool[key].send(JSON.stringify(result)); connectionPool[key].send(JSON.stringify(result));
} catch(err) { } catch(err) {
console.log("广播消息失败:", err); logError(`广播消息失败: ${err}`);
} }
} }
} }
...@@ -30,10 +27,8 @@ export async function initSocketServer(port) { ...@@ -30,10 +27,8 @@ export async function initSocketServer(port) {
Socket.createServer(port, function (wss) { Socket.createServer(port, function (wss) {
wss.on('connection', function(ws, req) { wss.on('connection', function(ws, req) {
let ip = analysisUserUrl(req); let ip = analysisUserUrl(req);
console.log("连接成功 => userId:", ip);
connectionPool[ip] = ws; connectionPool[ip] = ws;
ws.on('message', function(data) { ws.on('message', function(data) {
//回应心跳包 //回应心跳包
if (data == 'i am heart') ws.send(JSON.stringify({success:true, code:199})); if (data == 'i am heart') ws.send(JSON.stringify({success:true, code:199}));
...@@ -42,77 +37,18 @@ export async function initSocketServer(port) { ...@@ -42,77 +37,18 @@ export async function initSocketServer(port) {
ws.on('close', function (data){ ws.on('close', function (data){
if ( ws._socket && ws._socket._peername && ws._socket._peername.address ) { if ( ws._socket && ws._socket._peername && ws._socket._peername.address ) {
let userId = ws._socket._peername.address; let userId = ws._socket._peername.address;
console.log("close", userId, data); console.log("close", userId);
delete connectionPool[userId]; delete connectionPool[userId];
} }
}); });
console.log('发送初始化车辆:', dataQueue.length ,'辆');
dataQueue.forEach(info => {
ws.send(JSON.stringify({code:200, success:true, data:info}));
});
});
console.log('socket server listen on port:', port);
});
}
//测试服务
let testQueue;
export async function initSocketServertest(port) { let {initList, count} = getDpData();
Socket.createServer(port, function (wss) { console.log(`前端连接本服务成功 => userId:${ip}, 发送初始化车辆:${count} 辆`);
wss.on('connection', function(ws, req) { initList.forEach(info => {
let ip = analysisUserUrl(req); ws.send(JSON.stringify({code:200, success:true, data:info}));
console.log("连接成功 => userId:", ip);
testQueue = ws;
ws.on('message', function(data) {
//回应心跳包
if (data == 'i am heart') ws.send('{success:true, code:199}');
});
ws.on('close', function (data){
if ( ws._socket && ws._socket._peername && ws._socket._peername.address ) {
let userId = ws._socket._peername.address;
console.log("close", userId, data);
delete connectionPool[userId];
}
}); });
}); });
console.log('socket server listen on port:', port);
}); });
}
export function callTestServer(num) {
let latitude = 31.177747;
let longitude = 121.611986;
let testData = {
"accLat":0.08,
"accLong":1.542,
"acceleration":0,//加速度
"altitude":-3276,//海拔高度
"canRecvTime":1660285379691,//接收数据时间
"direction":0,//方向
"drivemode":0,//驾驶模式
"latitude":31.177747,
"longitude":121.611986,
"mileage":12,
"positiontime":0,
"vehicleid":"",
"velocity":13,
"vin":"LSJE24090MS029920"
}
for (let i= 1; i <= 100; i++ ) {
let addData = JSON.parse(JSON.stringify(testData))
addData.vehicleid = ''+i;
addData.latitude = latitude + (num*i * (1 / 100000));
addData.longitude = longitude + (num * i * (1 / 100000));
console.log(num+"-"+i+' log:'+addData.longitude+ ' lat: '+addData.latitude);
testQueue.send(JSON.stringify(addData));
}
} }
\ No newline at end of file
...@@ -5,24 +5,23 @@ import { analysisXml } from "../util/myXML"; ...@@ -5,24 +5,23 @@ import { analysisXml } from "../util/myXML";
import { SYSTEMERRORENUM } from "./errorEnum"; import { SYSTEMERRORENUM } from "./errorEnum";
const os = require('os'); const os = require('os');
export let port; export let systemConfig = {
export let socketPort; port:9999,
socketPort:''
};
export let dbConfig;
export let appConfig = { export let appConfig = {
rightView:'', rightView:'',
cloudResource:'', cloudResource:'',
physicalResource:'', physicalResource:'',
mapPort:'', mapPort:'',
wsPath:'',
lng: "",//地图中心点
lat: "",//地图中心点
zoom: 14,//中心点配置
surveillanceVideo: "",//监控地址
}; };
export let mongoServerConstVal; let serverIp = "";
export let mySqlConfig;
let imagePathConfig = "";
export let lngConfig = "";
export let latConfig = "";
export let zoomConfig = "";
export let surveillanceVideoConfig = "";
const ConfigName = "serverConfig.xml"; const ConfigName = "serverConfig.xml";
export async function initConfig() { export async function initConfig() {
...@@ -32,23 +31,18 @@ export async function initConfig() { ...@@ -32,23 +31,18 @@ export async function initConfig() {
let configInfo:any = await analysisXml(configStr); let configInfo:any = await analysisXml(configStr);
if (!configInfo || !configInfo.config) console.log("xml中无配置加载"); if (!configInfo || !configInfo.config) console.log("xml中无配置加载");
else { else {
let {portConfig, socketPortConfig, rightView, leftView, mapView, imagePath, mapCenter, zoom, surveillanceVideo} = configInfo.config; //必要配置
if ( !getConf(portConfig)) throw new SysError(SYSTEMERRORENUM.初始化配置失败, 'serverConfig.xml中 缺少 port'); let integralConfig = [
if ( !getConf(socketPortConfig)) throw new SysError(SYSTEMERRORENUM.初始化配置失败, 'serverConfig.xml中 缺少 sockentPort'); "port", "socketPort", "rightView", {"leftView":["cloudResource", "physicalResource"] },
if ( !getConf(rightView)) throw new SysError(SYSTEMERRORENUM.初始化配置失败, 'serverConfig.xml中 缺少 rightView'); {"mapView":["mapPort", "online","broken", "token" ] }, "imagePath", {"mapCenter":["lng", "lat"]}, "zoom",
if ( !getConf(leftView) || !getConf(leftView[0].cloudResource) || !getConf(leftView[0].physicalResource) ) { "surveillanceVideo", "wsPath"
throw new SysError(SYSTEMERRORENUM.初始化配置失败, 'serverConfig.xml中 缺少 leftView 或 physicalResource || cloudResource'); ];
} checkConfig(integralConfig, configInfo.config);
if ( !getConf(mapView) || !getConf(mapView[0].online ) || !getConf(mapView[0].broken ) || !getConf(mapView[0].token ) ) {
throw new SysError(SYSTEMERRORENUM.初始化配置失败, 'serverConfig.xml中 缺少 mapView 或 online || broken || token'); let {port, socketPort, rightView, leftView, mapView, imagePath, mapCenter, zoom, surveillanceVideo, wsPath} = configInfo.config;
} systemConfig.port = port[0];
systemConfig.socketPort = socketPort[0];
if ( !getConf(imagePath) ) throw new SysError(SYSTEMERRORENUM.初始化配置失败, 'serverConfig.xml中 缺少 imagePath');
if ( !getConf(mapCenter) ) throw new SysError(SYSTEMERRORENUM.初始化配置失败, 'serverConfig.xml中 缺少 mapCenter');
if ( !getConf(zoom) ) throw new SysError(SYSTEMERRORENUM.初始化配置失败, 'serverConfig.xml中 缺少 zoom');
if ( !getConf(surveillanceVideo) ) throw new SysError(SYSTEMERRORENUM.初始化配置失败, 'serverConfig.xml中 缺少 surveillanceVideo');
port = portConfig[0];
socketPort = socketPortConfig[0];
//左屏 //左屏
appConfig.cloudResource = leftView[0].cloudResource[0]; appConfig.cloudResource = leftView[0].cloudResource[0];
appConfig.physicalResource = leftView[0].physicalResource[0]; appConfig.physicalResource = leftView[0].physicalResource[0];
...@@ -59,15 +53,17 @@ export async function initConfig() { ...@@ -59,15 +53,17 @@ export async function initConfig() {
appConfig.mapPort = mapView[0].mapPort[0] + "&online=" + online + "&broken=" + broken + "&token=" + token || appConfig.mapPort; appConfig.mapPort = mapView[0].mapPort[0] + "&online=" + online + "&broken=" + broken + "&token=" + token || appConfig.mapPort;
//右屏接口 //右屏接口
appConfig.rightView = rightView[0]; appConfig.rightView = rightView[0];
//图片地址
imagePathConfig = imagePath[0];
//地图中心点 //地图中心点
lngConfig = mapCenter[0].lng[0]; appConfig.lng = mapCenter[0].lng[0];
latConfig = mapCenter[0].lat[0]; appConfig.lat = mapCenter[0].lat[0];
//缩放比 //缩放比
zoomConfig = zoom[0]; appConfig.zoom = parseInt(zoom[0]);
//监控视频 //监控视频
surveillanceVideoConfig = surveillanceVideo[0]; appConfig.surveillanceVideo = surveillanceVideo[0];
//ws
appConfig.wsPath = wsPath[0];
serverIp = imagePath[0];
} }
console.log("config init success"); console.log("config init success");
...@@ -76,14 +72,31 @@ export async function initConfig() { ...@@ -76,14 +72,31 @@ export async function initConfig() {
throw new BizError("服务器配置解析错误 请检查根目录下 serverConfig.xml 文件是否正确"); throw new BizError("服务器配置解析错误 请检查根目录下 serverConfig.xml 文件是否正确");
} }
} }
function checkConfig(config, configData) {
config.forEach(item => {
if (typeof item == "object") {
for (let key in item) {
if (!configData[key] || !configData[key][0]) {
throw new SysError(SYSTEMERRORENUM.初始化配置失败, `serverConfig.xml中 缺少 ${key}`);
}
item[key].forEach( subItem => {
if (!configData[key][0][subItem] || !configData[key][0][subItem][0]) {
throw new SysError(SYSTEMERRORENUM.初始化配置失败, `serverConfig.xml中 ${key}缺少 ${subItem}`);
}
});
}
} else {
if (!configData[item] || !configData[item][0]) {
throw new SysError(SYSTEMERRORENUM.初始化配置失败, `serverConfig.xml中 缺少 ${item}`);
}
}
});
}
//获取内网地址 //获取内网地址
export function getImageIp() { export function getImageIp() {
return imagePathConfig; return serverIp;
} }
function getConf(conf, index = 0) {
if (!conf || !conf[index]) return false;
return true;
}
\ No newline at end of file
import moment = require("moment") import moment = require("moment")
import { ERRORENUM, SYSTEMERRORENUM } from "../../config/errorEnum"; import { ERRORENUM, SYSTEMERRORENUM } from "../../config/errorEnum";
import { appConfig, getImageIp, port } from "../../config/serverConfig"; import { appConfig, getImageIp, systemConfig } from "../../config/serverConfig";
import { BizError, SysError } from "../../util/bizError"; import { BizError, SysError } from "../../util/bizError";
import { get } from "../../util/request"; import { get } from "../../util/request";
// {key:"2021.01", count:"31km", autoCount:"45km"}, {key:"2021.02", count:"42km", autoCount:"75km"}, {key:"2020.02", count:"42km", autoCount:"75km"}, {key:"2022.08", count:"42km", autoCount:"75km"} // {key:"2021.01", count:"31km", autoCount:"45km"}, {key:"2021.02", count:"42km", autoCount:"75km"}, {key:"2020.02", count:"42km", autoCount:"75km"}, {key:"2022.08", count:"42km", autoCount:"75km"}
...@@ -79,9 +79,9 @@ async function getTestLicense() { ...@@ -79,9 +79,9 @@ async function getTestLicense() {
测试牌照分布.forEach( item => { 测试牌照分布.forEach( item => {
let {enterprise, cnt} = item; let {enterprise, cnt} = item;
let imgItem = `http://${getImageIp()}:${port}/img/${enterprise}.png`; let imgItem = `http://${getImageIp()}:${systemConfig.port}/img/${enterprise}.png`;
测试牌照分布data[imgItem] = cnt + "辆"; 测试牌照分布data[imgItem] = cnt + "辆";
测试牌照数 += cnt; 测试牌照数 += parseInt(cnt);
}) })
...@@ -224,7 +224,6 @@ export async function getCsgkData() { ...@@ -224,7 +224,6 @@ export async function getCsgkData() {
return {测试牌照分布data, result, 今日数据, 今日测试, 今日功能测试}; return {测试牌照分布data, result, 今日数据, 今日测试, 今日功能测试};
} }
//======
//月度测试时长分布 //月度测试时长分布
export async function getTestTotalTime() { export async function getTestTotalTime() {
......
import moment = require("moment");
import * as WebSocket from "ws" import * as WebSocket from "ws"
import { sendMsg } from "../../biz/jgfwnl/wsData"; import { broadcastMsg } from "../../biz/jgfwnl/wsData";
import { appConfig } from "../../config/serverConfig";
import { logConsole, logHandle } from "../../util/log"; import { logConsole, logHandle } from "../../util/log";
//连接锁 //连接锁
...@@ -24,10 +26,7 @@ let heartCount = 0; ...@@ -24,10 +26,7 @@ let heartCount = 0;
//心跳 //心跳
let heart = { let heart = {
timeout:40*1000,//40秒一次心跳包 timeout:40*1000,//40秒一次心跳包
serverTimeout:4*1000,//心跳包超时时间
timeoutObj:null, timeoutObj:null,
notRespontNum:3, //未响应次数阈值
serverTimeoutObj:null,
reconnectTimeout:5 * 1000, //重连延迟 reconnectTimeout:5 * 1000, //重连延迟
start:(ws) => { start:(ws) => {
if (!heartCount) { if (!heartCount) {
...@@ -36,61 +35,48 @@ let heart = { ...@@ -36,61 +35,48 @@ let heart = {
} }
//消除延时器 //消除延时器
heart.timeoutObj && clearTimeout(heart.timeoutObj);
heart.serverTimeoutObj && clearTimeout(heart.serverTimeoutObj); heart.timeoutObj && clearInterval(heart.timeoutObj);
//次数限制
let notRespontCount = heart.notRespontNum;
heart.timeoutObj = setTimeout( () => { heart.timeoutObj = setInterval( () => {
//发送心跳包 //发送心跳包
console.log("客户端 发送心跳包"); console.log("本机call目标服务 发送心跳包");
ws.send("i am heart"); ws.send("i am heart");
}, heart.timeout);
//计算答复时间
heart.serverTimeoutObj = setTimeout( () => {
if ( notRespontCount > 0 ) notRespontCount --;
else ws.close();//超过未响应阈值 关闭连接
}, heart.serverTimeout);
}, heart.timeout)
}, },
reset: () => {//重置 reset: () => {//重置
clearTimeout(heart.serverTimeoutObj); clearInterval(heart.timeoutObj);
clearTimeout(heart.timeoutObj);
} }
} }
//ws客户端 //ws客户端
async function createSocket() { async function createSocket() {
let path = "ws://10.51.50.136:8090/ws/v1"; let ws = new WebSocket(appConfig.wsPath, {perMessageDeflate: false});
// let path = "ws://192.168.0.105:9797"
let ws = new WebSocket(path, {perMessageDeflate: false});
ws.onclose = async (err) => { ws.onclose = async (err) => {
console.log("连接关闭: ", err); console.log("连接关闭: ", err);
lockReconnect = false; lockReconnect = false;
heartCount = 0; heartCount = 0;
heart.reset();
//断线重连 //断线重连
reconnect(); reconnect();
console.log("客户端 关闭");
} }
ws.onmessage = (msg) => { ws.onmessage = (msg) => {
//接收数据 //接收数据
heart.start(ws);
stats(msg.data); stats(msg.data);
} }
ws.onerror = (error) => { ws.onerror = (error) => {
ws.close(error.message); ws.close();
} }
ws.onopen = () => { ws.onopen = () => {
heart.start(ws); heart.start(ws);
} }
console.log(`连接汽车数据socket服务: ${appConfig.wsPath} 成功`);
} }
export async function initWSData() { export async function initWSData() {
...@@ -98,33 +84,62 @@ export async function initWSData() { ...@@ -98,33 +84,62 @@ export async function initWSData() {
} }
//在线车辆 //在线车辆
let distinctMap = {};//{id:1}
let dp = {};//数据池 {"id":{lastMs:最新的时间, list:[] } } let dp = {};//数据池 {"id":{lastMs:最新的时间, list:[{},{},{}], index:0 } }
let dpNewDate = '';
export function stats(data) { export function stats(data) {
let dateFormat = moment().format('YYYYMMDD');
if (!dpNewDate) dpNewDate = dateFormat;
let dataType = typeof data; let dataType = typeof data;
if (dataType == 'object') { if (dataType == "string") {
console.log(data);
} else if (dataType == "string") {
try{ try{
let dataJson = JSON.parse(data); let dataJson = JSON.parse(data);
let {vehicleid, latitude, longitude} = dataJson; let {vehicleid, latitude, longitude, positiontime, canRecvTime} = dataJson;
distinctMap[vehicleid] = 1; broadcastMsg({lng:longitude||0.0, lat:latitude||0.0, vehicleid});
sendMsg({lng:longitude||0.0, lat:latitude||0.0, vehicleid}); //加入到缓存
let lastMs = positiontime || canRecvTime;
if ( lastMs ) {//数据包里有时间就缓存
checkData(dateFormat);
if ( !dp[vehicleid] ) dp[vehicleid] = {lastMs, list:[], index:0 };//初始化缓存
dp[vehicleid].list[dp[vehicleid].index] = {lng:longitude||0.0, lat:latitude||0.0, vehicleid, lastMs};
dp[vehicleid].index += 1;
if (dp[vehicleid].index > 4) dp[vehicleid].index = 0;
}
} catch(err) { } catch(err) {
console.log(data); logHandle("ws 返回数据不是json --> "+ data);
logHandle("ws 返回数据不是json"+ data)
//todo 加日志
} }
} else {
logHandle(`ws 返回数据不符合规范 类型:${dataType} --> `+ data)
} }
//其他格式数据抛弃
} }
function checkData(time) {
if (time != dpNewDate) {
dpNewDate = time;
dp = {};
}
}
export function getDpData() {
let result = [];
for (let key in dp) {
dp[key].list.forEach(info => {
result.push(info);
});
}
result.sort( (a, b) => {return a.lastMs - b.lastMs});
let initList = [];
result.forEach(info => {
let {lng, lat,vehicleid, lastMs} = info;
initList.push({lng, lat, vehicleid});
});
return {initList, count:Object.keys(dp).length};
}
export function getOnlieCarCount() { export function getOnlieCarCount() {
return Object.keys(distinctMap).length; return Object.keys(dp).length;
} }
/* data 数据长这样 /* data 数据长这样
......
let fs = require('fs');
const xlsx = require('node-xlsx');
const path = require('path');
//excel的名字
//const excelName = "其他数据模板.xlsx";
// const excelAnalysisName = "其他数据规则.xlsx";
const excelName = "安亭汽车城数据模板.xlsx";
const excelAnalysisName = "安亭汽车城解析规则.xlsx";
let typeEnum = {
"柱状数据":1,
"列表数据":1,
"单轴多柱状数据":1,
"双轴多柱状数据":1,
}
function changeDataName(str) {
let result = str.replace(/[()""“”/()-]/, "_");
for (let i =0; i < 10; i++) {
result = result.replace(/[()""“”/()-]/, "_");
}
return result;
}
let createBizAndDataConfigMap = {
};
//配置解析excel
function analysisConfigExcel() {
const workSheetsFromFile = xlsx.parse(`../res/${excelAnalysisName}`);
let sheetMap = {};
let sheetList = [];
for (let i = 0; i < workSheetsFromFile.length; i++) {
let sheetInfo = workSheetsFromFile[i];
sheetMap[sheetInfo.name] = sheetInfo.data;
sheetList.push(sheetInfo);
}
return sheetMap
}
function createConfig() {
let excelData = analysisConfigExcel();
for (let configSheetName in excelData) {
let data = excelData[configSheetName];
for (let y = 1; y < data.length; y++) {
let valueList = data[y];
let pageName = valueList[0];
let sheetName = valueList[1];
let type = valueList[2];
let dataName = changeDataName(valueList[3]);
let title = valueList[4];
let unit = valueList[5];
let total = valueList[6];
let percent = valueList[7];
let titleList = valueList[8] ? JSON.parse(valueList[8]) : "";
let keyValueObj = valueList[9] ? JSON.parse(valueList[9]) : "" ;
if (!createBizAndDataConfigMap[pageName] ) createBizAndDataConfigMap[pageName] = {sheetName, apiList:[]};
createBizAndDataConfigMap[pageName].apiList.push({ type ,dataName ,title ,unit ,total ,percent, titleList, keyValueObj });
}
}
}
createConfig();
//创建data层
function createData() {
let str = `
import { limitEnteNameString, changeDataName } from "../util/tools";
import { planarArrBecomeKeyValueData, planarArrBecomeChartData, planarArrBecomeStringListData, planarArrBecomeListData} from "../cal/excelEnter";
import { getExcelDataBySheetName } from "../util/analysisExcel";
`;
for (let pangeName in createBizAndDataConfigMap) {
let { sheetName } = createBizAndDataConfigMap[pangeName];
let forKeyValueList = [];
let forChartList = [];
let forStringList = [];
let forListData = [];
createBizAndDataConfigMap[pangeName].apiList.forEach( info => {
if (info.type == "双轴多柱状数据" || info.type == "单轴多柱状数据" || info.type == "柱状数据") forChartList.push(info.dataName);
else if (info.type == "键值数据") forKeyValueList.push(info.dataName);
else if (info.type == "列表数据") forListData.push(info.dataName);
else if (info.type == "字符数据") forStringList.push(info.dataName);
});
str += `
export function get${sheetName}() {
let bolckDataList = getExcelDataBySheetName('${excelName}', '${sheetName}');
let result = {};
let forKeyValueList = ${JSON.stringify(forKeyValueList)};
let forChartList = ${JSON.stringify(forChartList)};
let forStringList = ${JSON.stringify(forStringList)};
let forListData = ${JSON.stringify(forListData)};
for (let i = 0; i < bolckDataList.length; i++) {
let {blockData, blockTitle} = bolckDataList[i];
let changeName = changeDataName(blockTitle);
if (forKeyValueList.indexOf(changeName) > -1 ) result[changeName] = planarArrBecomeKeyValueData(blockData);
if (forChartList.indexOf(changeName) > -1 ) result[changeName] = planarArrBecomeChartData(blockData);
if (forStringList.indexOf(changeName) > -1 ) result[changeName] = planarArrBecomeStringListData(blockData);
if (forListData.indexOf(changeName) > -1 ) result[changeName] = planarArrBecomeListData(blockData);
}
return result;
}`;
}
let path = `./data/analysisExcelData1.ts`;
fs.access(path, (err) => {
if (!err) {
console.error(path, "文件已存在");
return;
}
fs.writeFileSync(path, str);
console.log(path, "创建文件成功")
});
}
//创建biz层
function createBiz(){
for (let pageName in createBizAndDataConfigMap) {
let { apiList, sheetName } = createBizAndDataConfigMap[pageName];
let thisBizData = getBizStr(apiList, sheetName);
let path = `./biz/${pageName}.ts`;
fs.access(path, (err) => {
if (!err) {
console.error(path, "文件已存在");
return;
}
fs.writeFileSync(path, thisBizData);
console.log(path, "创建文件成功")
});
}
}
function getBizStr(apiList, sheetName) {
let str = `
import { getKeyValueNumberOutData, getChartOutData, getKeyValueNotNumberOutData, getListOutData, getScatterFigureOutData, getStringOutData } from "../cal/out";
import { get${sheetName} } from "../data/analysisExcelData";
`;
str += `
export function getData(req, res) {
let ret:any = {};
let excelData:any = get${sheetName}();
`;
apiList.forEach((info, index) => {
let {dataName, unit, total, percent, type, titleList, keyValueObj} = info;
const apiName = `api${index+1}`;
let functionStr = "";
switch(type) {
case "键值数据": functionStr = `getKeyValueNumberOutData`;
break;
case "柱状数据":
case "单轴多柱状数据":
case "双轴多柱状数据": functionStr = `getChartOutData`;
break;
case "列表数据": functionStr = `getListOutData`;
break;
case "字符串数据":
case "图片": functionStr = `getStringOutData`;
break;
};
let subStr = `ret["${apiName}"] = ${functionStr}("${dataName}", excelData.${dataName} );`;
str+=
`${subStr}
`
});
str += `
res.send(ret);
}
`
return str;
}
//创建Router层
function createRouter() {
let importName =``;
let routergetName=``;
let routerpostName=``;
for (let pageName in createBizAndDataConfigMap) {
importName+=`
import * as ${pageName}Biz from '../biz/${pageName}';`;
routergetName+=`
httpServer.get('/${pageName}', asyncHandler(${pageName}Biz.getData));`;
routerpostName+=`
httpServer.post('/${pageName}', asyncHandler(${pageName}Biz.getData));`;
}
let str=`
import * as asyncHandler from 'express-async-handler'
${importName}
export function setRouter(httpServer){
${routergetName}
${routerpostName}
}`;
let path = `./routers/router1.ts`;
fs.access(path, (err) => {
if (!err) {
console.error(path, "文件已存在");
return;
}
fs.writeFileSync(path, str);
console.log(path, "创建router文件成功")
});
}
createData();
createBiz();
createRouter();
import { callTestServer, initSocketServer, initSocketServertest } from "./biz/jgfwnl/wsData"; import { initSocketServer } from "./biz/jgfwnl/wsData";
import { initConfig, port, socketPort } from "./config/serverConfig"; import { initConfig, systemConfig} from "./config/serverConfig";
import { getCsgkData, initData } from "./data/interface/interfaceService"; import { getCsgkData, initData } from "./data/interface/interfaceService";
import { initWSData } from "./data/interface/wsData"; import { initWSData } from "./data/interface/wsData";
import { httpServer } from "./net/http_server"; import { httpServer } from "./net/http_server";
...@@ -8,11 +8,10 @@ import { httpServer } from "./net/http_server"; ...@@ -8,11 +8,10 @@ import { httpServer } from "./net/http_server";
async function lanuch() { async function lanuch() {
await initConfig();//初始化配置解析 await initConfig();//初始化配置解析
await initWSData(); await initWSData();
httpServer.createServer(port);
await initSocketServer(socketPort);
await initData(); await initData();
await initSocketServer(systemConfig.socketPort);
httpServer.createServer(systemConfig.port);
console.log('This indicates that the server is started successfully.'); console.log('This indicates that the server is started successfully.');
} }
lanuch(); lanuch();
\ No newline at end of file
...@@ -9,6 +9,6 @@ export class Socket { ...@@ -9,6 +9,6 @@ export class Socket {
maxPayload:9999, maxPayload:9999,
}); });
callback(wss); callback(wss);
console.log("configCenter socketServer listen on port:"+port); console.log("socketServer listen on port:"+port);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment