直接上代码,写的很乱
服务端:
var express=require('express');
var app=express();
var fs =require('fs');
var net=require('net');
var http=require('http').createServer(app);
var io=require('socket.io').listen(http);
var os=require('os');
//设置默认IP和端口号
var IPaddr='192.168.0.101'
var DataPort=3100;
var CmdPort=4100;
//设置新IP和端口号
var newIPaddr=0;
var newDataPort=0;
var newCmdPort=0;
//给EventEmitter设置最大监听
var EventEmitter = require('events').EventEmitter;
var ee = new EventEmitter();
//nodeServer需要的变量
var nodeServer = new net.Socket();
var client = new net.Socket();
var ExBuffer = require('./ExBuffer');
var len = 4027;
var offset=4;
var dataNum=0;
var exBuffer = new ExBuffer().uint32Head().littleEndian();
var sbuf = new Buffer(4);
var haha=0;
// 存储客户端的WebSocket连接实例
var aSocket = null;
//创建服务器,监听8888端口(省略127.0.0.1)
var server = http.listen(8888,function () {
var host = server.address().address
var port = server.address().port
console.log("welcome to http://%s:%s", host, port)
});
ee.setMaxListeners(10);
app.use(express.static('public'));
app.get('/',function(req,res){
res.sendfile(__dirname+'/index.html');
});
// 同客户端建立连接
io.sockets.on('connection', function (socketIO) {
aSocket=socketIO;
// 测试用,连接成功
socketIO.emit("test","your websocket has connected");
//返回数据使用,控制C服务器
socketIO.on('fromWebClient', function (webClientData) {
console.log(webClientData);
var head=new Buffer([0xAA,0x01,0x11,0x11,0x11,0x11]);
var cmdData=new Buffer(webClientData);
var cmdControl=Buffer.concat([head,cmdData]);
console.log(cmdControl);
client.write(cmdControl);
});
socketIO.on('fromCmd',function(CmdData){
if(newIPaddr!=CmdData.IPaddr){
newIPaddr=CmdData.IPaddr;
}else(
console.log('newIPaddr is same')
)
if(newCmdPort!=parseFloat(CmdData.CmdPort)){
newCmdPort=parseFloat(CmdData.CmdPort);
connectCPort(newCmdPort,newIPaddr);
}else(
console.log('newCmdPort is same')
)
if(newDataPort!=parseFloat(CmdData.DataPort)){
newDataPort=parseFloat(CmdData.DataPort);
connectDPort(newDataPort,newIPaddr);
}else(
console.log('newDataPort is same')
)
})
});
// 从C服务器接收数据
nodeServer.on('data', function (data) {
dataNum=data.readInt32LE(6);
if(data.readUInt8(0)==170){
sbuf.writeUInt32LE(len,0);//写入包长
exBuffer.put(sbuf);
exBuffer.put(data);
}
else{
exBuffer.put(data);
}
console.log('nodeServer'+data.length);
});
//当nodeServer收到完整的数据包时
exBuffer.on('data', function(buffer) {
console.log('>> nodeServer receive data.length:'+buffer.length);
//console.log(buffer);
//console.log(buffer.readInt32LE(826));
haha++;
console.log(haha);
console.log('free mem : ' + Math.ceil(os.freemem()/(1024*1024)) + 'mb');
var useData=byteArrayUntil.getUseJson(buffer,offset);
console.log(useData.low);
console.log(useData.high);
//向客户端发送json数据
//判断websocket是否已经连接
if(aSocket!=null){
aSocket.emit('pushToWebClient',useData);
//客户端断开连接
aSocket.on('disconnect', function () {
console.log('DISCONNECTED FROM CLIENT');
});
}
});
// 为客户端添加“close”事件处理函数
nodeServer.on('close', function() {
console.log('nodeServer connection closed');
});
client.on('close',function(){
console.log('client connection closed')
})
//连接到C服务器DataPort端口
function connectDPort(DataPort,IPaddr){
nodeServer.connect(DataPort, IPaddr, function() {
console.log('CONNECTED TO:',IPaddr,DataPort);
// 建立连接后立即向服务器发送数据,服务器将收到这些数据
var receive = new Buffer([0xAA,0x02,0xFE]);
nodeServer.write(receive);
nodeServer.write('your'+ DataPort +'socket has connected');
});
nodeServer.on('error',function(err){
console.error(err);
nodeServer.destroy();
})
};
//连接到C服务器CmdPort端口
function connectCPort(CmdPort,IPaddr){
client.connect(CmdPort, IPaddr, function() {
console.log('CONNECTED TO:',IPaddr,CmdPort);
});
client.on('error',function(err){
console.error(err);
client.destroy();
})
}
//构造一个遍历函数,分别返回array或者json
var byteArrayUntil=new function(){
this.getUseData=function(data,offset){
var arr=[];
for(var i=0;i<dataNum;i++){
arr.push(data.readInt32LE(826+i*offset));
}
return arr;
}
this.getUseJson=function(data,offset){
var arr=[];
var low=null;
var high=null;
for(var i=0;i<dataNum;i++){
arr.push(data.readInt32LE(826+i*offset));
}
low=parseInt(data.readInt32LE(14)/1000);
high=parseInt(data.readInt32LE(18)/1000);
return {'hz':arr,
'low':low,
'high':high,
'num':dataNum};
}
}();
客户端js代码(html部分我就省了):
<script src="/socket.io/socket.io.js"></script>
<script src="js/jquery-3.1.1.min.js"></script>
<script src="js/echarts.js"></script>
<!--<script src="js/canvas.js"></script>-->
<script>
var myChart = echarts.init(document.getElementById('main'));
var i=0;
var inputValue = null;
var CandleChartOption = null;
var socket = io.connect();
//测试返回数据,连接成功
socket.on("test", function (data) {
//console.log(data);
});
//接收转发数据,格式json
socket.on('pushToWebClient', function (useData) {
//i++;
//console.log(i);
//console.log(useData);
processingData(useData);
});
socket.on('disconnect', function() {
});
function processingData(jsonData){
var newData = jsonData;
var low=newData.low; //数据低频
var high=newData.high; //数据高频
var num=newData.num;
var arr1=[];
var off=(high-low)/num;
for(var k=low;k<=high;k=k+off){
arr1.push(k);
var xArray={'dbm':arr1};
}
//console.log(arr1);
CandleChartOption = setOption(xArray,newData);
myChart.setOption(CandleChartOption);
};
function setOption(x,y){
var xData= x.dbm;
var yData= y.hz;
var option = {
title: {
text: 'canvas'
},
tooltip: {
trigger: 'axis'
},
xAxis: {
data: xData,
boundaryGap: false,
axisLabel :{
interval:49
}
},
yAxis: {
boundaryGap: [0,'100%'],
splitLine: {
show: false
}
},
toolbox: {
left: 'center',
feature: {
dataZoom: {
yAxisIndex: 'none'
},
restore: {},
saveAsImage: {}
}
},
series: {
name: 'canvas',
type: 'line',
data: yData,
markLine: {
silent: true,
data: [{
yAxis: 50000
}, {
yAxis: 58000
}, {
yAxis: 64000
}, {
yAxis: 71000
}, {
yAxis: 79000
}]
}
}
}
return option;
}
function tijiao(){
var index=document.getElementById("select").selectedIndex;
var select = document.getElementById("select").options[index].value;
var val = document.getElementById("val").value;
inputValue=select+val;
socket.emit('fromWebClient',inputValue);
}
function xiugai(){
var IPaddr= document.getElementById("IP").value;
var CmdPort= document.getElementById("CmdPort").value;
var DataPort= document.getElementById("DataPort").value;
cmdData={"IPaddr":IPaddr,
"CmdPort":CmdPort,
"DataPort":DataPort
};
socket.emit('fromCmd',cmdData);
}
</script>
是这样的,有一台内置服务器的仪器,我需要从里面接受tcp数据,显示到网页上,100ms刷新一次,一次4kb的数据,用到了socket.io和echarts,代码中的Exbuffer是用来接受tcp数据防止粘包的。
问题:我分别试了三台电脑,nodejs都是统一版本v4.5.0的,两台打开浏览器就内存不够崩溃,一台可以撑一会然后浏览器崩溃。我用了os看内存,而且用了eventemitter.setMaxlistener,电脑内存至少还有3000多M,所以想问问究竟哪里出了问题,还有怎么改?
其实很简单,一是代码有个地方写错了,结果是无穷大。
二是echarts不怎么样,对付高刷新还是不太行啊。。。这种图表内存处理不太好
换了hcharts,好太多了。。。