Javascript 数组不会更改它';拼接后的数据。范围问题?
我有一个tcp服务器,我将所有客户机数据存储在客户机阵列中。 所以当有人断开连接时,我就把它们拼接起来Javascript 数组不会更改它';拼接后的数据。范围问题?,javascript,arrays,node.js,Javascript,Arrays,Node.js,我有一个tcp服务器,我将所有客户机数据存储在客户机阵列中。 所以当有人断开连接时,我就把它们拼接起来 clients.splice(clients.indexOf(socket), 1); 我有一个显示所有在线用户的功能。它只是从客户端数组中获取数据并显示给我 function showOnline(){ console.log("Show user list"); console.log("clients.length = " + clients.length); } a
clients.splice(clients.indexOf(socket), 1);
我有一个显示所有在线用户的功能。它只是从客户端数组中获取数据并显示给我
function showOnline(){
console.log("Show user list");
console.log("clients.length = " + clients.length);
}
app.js文件顶部公布的客户端阵列
var clients = []; <- here it is
var http = require('http');
var net = require('net');
因此,客户端阵列中只有1个用户。然后我使用show online users功能,它会给我这样的日志
LOG
2016-03-04 22:06:41 - Show user list
clients.length = 2
它显示有2个用户。这怎么可能?
这是范围问题吗?或者可能是什么?谢谢你的回复
来源。
我想我的插座有问题。这段代码可以工作,但它运行的时间越长,我在客户机阵列中保留的虚拟客户机就越多
var clients = [];
var packetReg = /(ART\D\d{4}(.*?)\DAND)/g;
var serverUrl = "http://localhost:4000/"
// Exit packet
var p = {
exit: true
};
var ePacket = 'ART|' + randomNumber(1000, 9000) + JSON.stringify(p) + '|AND';
var fs = require('fs');
var http = require('http');
var https = require('https');
var net = require('net');
var url = require('url');
http.createServer(function (req, res) {
var queryData = url.parse(req.url, true).query;
res.writeHead(200, {"Content-Type": "text/html; charset=utf-8"});
if (queryData.clean) {
kick();
} else if (queryData.expel) {
kick();
} else if (queryData.list) {
showUserList();
}
else {
res.writeHead(302, {'Location': 'https://localhost'});
res.end();
}
function kick(all){
if (queryData.expel){
LOG("Expel user " + queryData.expel + " cmd");
}
else LOG("Kick all cmd");
clients.forEach(function (client) {
if (queryData.expel){
if (client.key != queryData.expel) return;
}
client.write(ePacket);
});
if (queryData.expel){
res.end("done");
}
else {
cleanOnline();
res.end("disconnected - " + clients.length);
}
}
function showUserList(){
LOG("Show user list");
var temp = 'Clients: ' + clients.length + generateButton('?clean=1', 'Kick all') + '<br>';
clients.forEach(function (client) {
temp += 'User: ' + client.name + ' Key: ' + client.key + generateButton('?expel=' + client.key, 'Kick') + '<br>';
});
console.log("clients.length = " + clients.length);
res.end(temp);
}
function generateButton(link, text){
return ' <a href="' + serverUrl + link + '" target="_blank" onClick="window.location.reload()"><button>' + text + '</button></a> ';
}
}).listen(4000, function(){
console.log('listening http on port 4000');
});
var tcpSocket = net.createServer();
tcpSocket.on('connection', function (socket) {
socket.setNoDelay(true);
socket.banned = false;
socket.isAdmin = false;
socket.isModerator = false;
socket.name = 'newUser'
socket.key = ''
socket.armbuf = '';
clients.push(socket);
LOG("New connection #" + clients.length);
// Exit packet that close opened software
socket.on('doExit', function () {
LOG("Send exit packet");
var p = {
exit: true
};
socket.write('ART|' + randomNumber(1000, 9000) + JSON.stringify(p) + '|AND');
socket.destroy();
});
// Init packet
socket.on('init', function (newData) {
LOG("Init packet");
//newData.data = packet with key from my program
//I find out if users start my program few times then they will be added few times at clients array.
//So i want to prevent that with that function. It finds sockets with same key and just disconnect them except for the last socket.
//
FindAndCleanDuplicateSockets(newData.data, socket);
var tempSocket = findSocket(socket);
tempSocket.socket.key = newData.data;
LOG("Send request to localhost about key " + tempSocket.socket.key);
https.get('https://localhost/tgo/api/?apiRequest&key=' + tempSocket.socket.key, (res) => {
var initData = '';
res.on('data', function (chunk) {
initData += chunk;
});
res.on('end', function() {
LOG("Receive answer from localhost - " + initData.toString());
var a = JSON.parse(initData.toString());
if (a.data = "OK"){
tempSocket.socket.name = a.name;
tempSocket.socket.banned = !Boolean(a.chatBan);
if (a.type == "admin")
tempSocket.socket.isAdmin = true;
else if (a.type == "moderator")
tempSocket.socket.isModerator = true;
updateSocket(tempSocket);
broadcast(packetMaker(tempSocket.socket.name, 'start'), socket);
}
else socket.emit('doExit');
});
}).on('error', (e) => {
socket.emit('doExit');
});
});
//When user send ping packet
socket.on('ping', function (newData) {
//LOG("Ping packet");
var p = {
currentTime: currentTime()
};
socket.write('ART|' + randomNumber(1000, 9000) + JSON.stringify(p) + '|AND');
});
// When user change his name
socket.on('newName', function (newData) {
LOG("User change name from " + socket.name + " to " + newData.data);
var tempSocket = findSocket(socket);
tempSocket.socket.name = newData.data;
updateSocket(tempSocket);
});
//When user send new message packet
socket.on('newMsg', function (newData) {
LOG("newMsg packet");
var tempSocket = findSocket(socket);
if (tempSocket.socket.banned) {
LOG('User ' + tempSocket.socket.key + ' chat is banned');
return;
}
var type = 'msg';
if (tempSocket.socket.isAdmin)
type = 'admin';
else if (tempSocket.socket.isModerator)
type = 'moderator';
broadcast(packetMaker(tempSocket.socket.name, type, String(newData.data)), socket);
});
// Handle incoming messages from clients.
socket.on('data', function (newData) {
var d = String(newData);
//LOG('Received data: ' + d);
// I find that socket bacause i use buffer to store data. If i won't do that it will give me "is not defined" error
var tempSocket = findSocket(socket);
tempSocket.socket.armbuf += d;
var dataArray = tempSocket.socket.armbuf.match(packetReg);
if (dataArray != null && dataArray.length > 0){
dataArray.forEach(function (match) {
tempSocket.socket.armbuf = tempSocket.socket.armbuf.replace(match, "");
if (match.startsWith('ART|') && match.endsWith('|AND')) {
var j = JSON.parse(cleanPacket(match));
switch (j.type) {
case 'init':
socket.emit('init', j);
break;
case 'ping':
socket.emit('ping', j);
break;
case 'newName':
socket.emit('newName', j);
break;
case 'newMsg':
socket.emit('newMsg', j);
break;
default:
break;
}
}
else console.log('Bad packet: ' + match);
//LOG("armbuf.length = " + tempSocket.socket.armbuf.length);
});
}
updateSocket(tempSocket);
});
socket.on('error',function(error) {
socket.end();
});
socket.on('close',function() {
var tempSocket = findSocket(socket);
LOG("Send logout notification to localhost - " + tempSocket.socket.key);
// Send info to api that user logout
https.get('https://localhost/tgo/api/?logout&key=' + tempSocket.socket.key);
// Broadcast data to all users that client is logout
broadcast(packetMaker(tempSocket.socket.name, 'exit'), socket);
console.log("clients.indexOf(socket) = " + clients.indexOf(socket));
console.log("clients.length = " + clients.length);
// Delete user from clients array
clients.splice(clients.indexOf(socket), 1);
console.log("after splice clients.length = " + clients.length);
LOG("Close from API - " + tempSocket.socket.key);
socket.destroy();
});
function cleanPacket(packet){
packet = packet.replace("ART|", "");
packet = packet.replace("|AND", "");
return packet.substring(4);
}
function findSocket(socket){
var socketData = {
'id': clients.indexOf(socket),
'socket': clients[clients.indexOf(socket)]
};
return socketData;
}
function FindAndCleanDuplicateSockets(key, exclude){
clients.forEach(function (client) {
if (client == exclude && client.key != key) return;
LOG("User already exist in array. Delete old socket");
client.emit('doExit');
});
}
function findAllSocketsByKey(key, excludeSocket){
var sockets = [];
clients.forEach(function (client) {
if (client == excludeSocket && client.key != key) return;
sockets.push(client);
});
return sockets;
}
function updateSocket(tempSocket){
clients[tempSocket.id] = tempSocket.socket;
}
// Send a message to all clients
function broadcast(message, sender) {
if (clients.length <= 0) return;
LOG('broadcast ' + message);
clients.forEach(function (client) {
// Don't want to send it to sender
if (client === sender) return;
client.write(message);
});
}
function packetMaker(userName, packetType, userMsg){
var p = {
currentTime: currentTime(),
chat: {
user: userName,
type: packetType
}
};
if (typeof userMsg != 'undefined')
p['chat']['msg'] = userMsg;
return 'ART|' + randomNumber(1000, 9000) + JSON.stringify(p) + '|AND';
}
});
tcpSocket.listen(5000, function(){
console.log('listening tcpSocket on port 5000');
cleanOnline();
});
function cleanOnline(){
console.log('Clean DB online');
//https.get('https://localhost/tgo/api/?apiCleanOnline');
}
function LOG(data){
console.log(currentTime() + " - " + data);
}
function randomNumber(min, max)
{
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function currentTime() {
var date = new Date();
var hour = date.getHours();
hour = (hour < 10 ? "0" : "") + hour;
var min = date.getMinutes();
min = (min < 10 ? "0" : "") + min;
var sec = date.getSeconds();
sec = (sec < 10 ? "0" : "") + sec;
var year = date.getFullYear();
var month = date.getMonth() + 1;
month = (month < 10 ? "0" : "") + month;
var day = date.getDate();
day = (day < 10 ? "0" : "") + day;
return year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec;
}
var客户机=[];
var packetReg=/(ART\D\D{4}(.*?\D)/g;
var serverUrl=”http://localhost:4000/"
//出口数据包
var p={
退出:对
};
var-ePacket='ART |'+随机数(10009000)+JSON.stringify(p)+'|和';
var fs=需要('fs');
var http=require('http');
var https=require('https');
var net=要求的(‘净额’);
var url=require('url');
http.createServer(函数(req,res){
var queryData=url.parse(req.url,true).query;
res.writeHead(200,{“内容类型”:“text/html;charset=utf-8”});
if(queryData.clean){
踢();
}else if(queryData.expel){
踢();
}else if(queryData.list){
showUserList();
}
否则{
res.writeHead(302,{'Location':'https://localhost'});
res.end();
}
功能踢(全部){
if(queryData.expel){
日志(“排除用户”+queryData.Expel+“cmd”);
}
else日志(“Kick all cmd”);
clients.forEach(函数(客户端){
if(queryData.expel){
如果(client.key!=queryData.expel)返回;
}
client.write(ePacket);
});
if(queryData.expel){
决议结束(“完成”);
}
否则{
cleanOnline();
res.end(“断开连接-”+客户端长度);
}
}
函数showUserList(){
日志(“显示用户列表”);
var temp='Clients:'+Clients.length+generateButton('clean=1','Kick all')+'
;
clients.forEach(函数(客户端){
temp+='User:'+client.name+'Key:'+client.Key+generateButton('?expel='+client.Key,'Kick')+'
';
});
console.log(“clients.length=“+clients.length”);
res.end(温度);
}
函数生成按钮(链接、文本){
返回“”;
}
}).listen(4000,函数(){
log(“在端口4000上侦听http”);
});
var tcpSocket=net.createServer();
tcpSocket.on('connection',函数(套接字){
socket.setNoDelay(真);
socket.banked=false;
socket.isAdmin=false;
socket.isModerator=false;
socket.name='newUser'
socket.key=“”
socket.armbuf='';
客户端。推(插座);
日志(“新连接#”+客户端.长度);
//退出关闭已打开软件的数据包
socket.on('doExit',function(){
日志(“发送退出包”);
var p={
退出:对
};
socket.write('ART |'+随机数(10009000)+JSON.stringify(p)+'| AND');
socket.destroy();
});
//初始化包
socket.on('init',函数(newData){
日志(“初始数据包”);
//newData.data=包含来自我的程序的密钥的数据包
//我发现,如果用户启动我的程序几次,那么他们将在客户端阵列中添加几次。
//所以我想用这个函数来防止这种情况。它会找到具有相同密钥的套接字,只需断开它们,除了最后一个套接字。
//
FindAndCleanDuplicateSockets(newData.data,socket);
var tempSocket=findSocket(socket);
tempSocket.socket.key=newData.data;
日志(“向本地主机发送关于密钥的请求”+tempSocket.socket.key);
https.get('https://localhost/tgo/api/?apiRequest&key='+tempSocket.socket.key,(res)=>{
var initData='';
res.on('data',函数(块){
initData+=chunk;
});
res.on('end',function(){
日志(“从本地主机接收应答-”+initData.toString());
var a=JSON.parse(initData.toString());
如果(a.data=“确定”){
tempSocket.socket.name=a.name;
tempSocket.socket.banked=!Boolean(a.chatBan);
如果(a.type==“admin”)
tempSocket.socket.isAdmin=true;
否则如果(a.type==“主持人”)
tempSocket.socket.isModerator=true;
更新套接字(tempSocket);
广播(packetMaker(tempSocket.socket.name,'start')、socket);
}
else socket.emit('doExit');
});
}).on('错误',(e)=>{
emit('doExit');
});
});
//当用户发送ping数据包时
socket.on('ping',函数(newData){
//日志(“Ping数据包”);
var p={
currentTime:currentTime()
};
socket.write('ART |'+随机数(10009000)+JSON.stringify(p)+'| AND');
});
//当用户更改其名称时
socket.on('newName',函数(newData){
日志(“用户将名称从“+socket.name+”更改为“+newData.data”);
var tempSocket=findSocket(socket);
tempSocket.socket.name=newData.data;
更新套接字(tempSocket);
});
//当用户发送新消息包时
socket.on('newMsg',函数(newData){
日志(“新消息包”);
var tempSocket=findSocket(socket);
if(tempSocket.socket.banked){
日志('User'+tempSocket.socket.key+'chat被禁止');
返回;
}
变量类型='msg';
if(tempSocket.socket.isAdmin)
类型='admin';
else if(tempSocket.socket.isModerator)
var clients = [];
var packetReg = /(ART\D\d{4}(.*?)\DAND)/g;
var serverUrl = "http://localhost:4000/"
// Exit packet
var p = {
exit: true
};
var ePacket = 'ART|' + randomNumber(1000, 9000) + JSON.stringify(p) + '|AND';
var fs = require('fs');
var http = require('http');
var https = require('https');
var net = require('net');
var url = require('url');
http.createServer(function (req, res) {
var queryData = url.parse(req.url, true).query;
res.writeHead(200, {"Content-Type": "text/html; charset=utf-8"});
if (queryData.clean) {
kick();
} else if (queryData.expel) {
kick();
} else if (queryData.list) {
showUserList();
}
else {
res.writeHead(302, {'Location': 'https://localhost'});
res.end();
}
function kick(all){
if (queryData.expel){
LOG("Expel user " + queryData.expel + " cmd");
}
else LOG("Kick all cmd");
clients.forEach(function (client) {
if (queryData.expel){
if (client.key != queryData.expel) return;
}
client.write(ePacket);
});
if (queryData.expel){
res.end("done");
}
else {
cleanOnline();
res.end("disconnected - " + clients.length);
}
}
function showUserList(){
LOG("Show user list");
var temp = 'Clients: ' + clients.length + generateButton('?clean=1', 'Kick all') + '<br>';
clients.forEach(function (client) {
temp += 'User: ' + client.name + ' Key: ' + client.key + generateButton('?expel=' + client.key, 'Kick') + '<br>';
});
console.log("clients.length = " + clients.length);
res.end(temp);
}
function generateButton(link, text){
return ' <a href="' + serverUrl + link + '" target="_blank" onClick="window.location.reload()"><button>' + text + '</button></a> ';
}
}).listen(4000, function(){
console.log('listening http on port 4000');
});
var tcpSocket = net.createServer();
tcpSocket.on('connection', function (socket) {
socket.setNoDelay(true);
socket.banned = false;
socket.isAdmin = false;
socket.isModerator = false;
socket.name = 'newUser'
socket.key = ''
socket.armbuf = '';
clients.push(socket);
LOG("New connection #" + clients.length);
// Exit packet that close opened software
socket.on('doExit', function () {
LOG("Send exit packet");
var p = {
exit: true
};
socket.write('ART|' + randomNumber(1000, 9000) + JSON.stringify(p) + '|AND');
socket.destroy();
});
// Init packet
socket.on('init', function (newData) {
LOG("Init packet");
//newData.data = packet with key from my program
//I find out if users start my program few times then they will be added few times at clients array.
//So i want to prevent that with that function. It finds sockets with same key and just disconnect them except for the last socket.
//
FindAndCleanDuplicateSockets(newData.data, socket);
var tempSocket = findSocket(socket);
tempSocket.socket.key = newData.data;
LOG("Send request to localhost about key " + tempSocket.socket.key);
https.get('https://localhost/tgo/api/?apiRequest&key=' + tempSocket.socket.key, (res) => {
var initData = '';
res.on('data', function (chunk) {
initData += chunk;
});
res.on('end', function() {
LOG("Receive answer from localhost - " + initData.toString());
var a = JSON.parse(initData.toString());
if (a.data = "OK"){
tempSocket.socket.name = a.name;
tempSocket.socket.banned = !Boolean(a.chatBan);
if (a.type == "admin")
tempSocket.socket.isAdmin = true;
else if (a.type == "moderator")
tempSocket.socket.isModerator = true;
updateSocket(tempSocket);
broadcast(packetMaker(tempSocket.socket.name, 'start'), socket);
}
else socket.emit('doExit');
});
}).on('error', (e) => {
socket.emit('doExit');
});
});
//When user send ping packet
socket.on('ping', function (newData) {
//LOG("Ping packet");
var p = {
currentTime: currentTime()
};
socket.write('ART|' + randomNumber(1000, 9000) + JSON.stringify(p) + '|AND');
});
// When user change his name
socket.on('newName', function (newData) {
LOG("User change name from " + socket.name + " to " + newData.data);
var tempSocket = findSocket(socket);
tempSocket.socket.name = newData.data;
updateSocket(tempSocket);
});
//When user send new message packet
socket.on('newMsg', function (newData) {
LOG("newMsg packet");
var tempSocket = findSocket(socket);
if (tempSocket.socket.banned) {
LOG('User ' + tempSocket.socket.key + ' chat is banned');
return;
}
var type = 'msg';
if (tempSocket.socket.isAdmin)
type = 'admin';
else if (tempSocket.socket.isModerator)
type = 'moderator';
broadcast(packetMaker(tempSocket.socket.name, type, String(newData.data)), socket);
});
// Handle incoming messages from clients.
socket.on('data', function (newData) {
var d = String(newData);
//LOG('Received data: ' + d);
// I find that socket bacause i use buffer to store data. If i won't do that it will give me "is not defined" error
var tempSocket = findSocket(socket);
tempSocket.socket.armbuf += d;
var dataArray = tempSocket.socket.armbuf.match(packetReg);
if (dataArray != null && dataArray.length > 0){
dataArray.forEach(function (match) {
tempSocket.socket.armbuf = tempSocket.socket.armbuf.replace(match, "");
if (match.startsWith('ART|') && match.endsWith('|AND')) {
var j = JSON.parse(cleanPacket(match));
switch (j.type) {
case 'init':
socket.emit('init', j);
break;
case 'ping':
socket.emit('ping', j);
break;
case 'newName':
socket.emit('newName', j);
break;
case 'newMsg':
socket.emit('newMsg', j);
break;
default:
break;
}
}
else console.log('Bad packet: ' + match);
//LOG("armbuf.length = " + tempSocket.socket.armbuf.length);
});
}
updateSocket(tempSocket);
});
socket.on('error',function(error) {
socket.end();
});
socket.on('close',function() {
var tempSocket = findSocket(socket);
LOG("Send logout notification to localhost - " + tempSocket.socket.key);
// Send info to api that user logout
https.get('https://localhost/tgo/api/?logout&key=' + tempSocket.socket.key);
// Broadcast data to all users that client is logout
broadcast(packetMaker(tempSocket.socket.name, 'exit'), socket);
console.log("clients.indexOf(socket) = " + clients.indexOf(socket));
console.log("clients.length = " + clients.length);
// Delete user from clients array
clients.splice(clients.indexOf(socket), 1);
console.log("after splice clients.length = " + clients.length);
LOG("Close from API - " + tempSocket.socket.key);
socket.destroy();
});
function cleanPacket(packet){
packet = packet.replace("ART|", "");
packet = packet.replace("|AND", "");
return packet.substring(4);
}
function findSocket(socket){
var socketData = {
'id': clients.indexOf(socket),
'socket': clients[clients.indexOf(socket)]
};
return socketData;
}
function FindAndCleanDuplicateSockets(key, exclude){
clients.forEach(function (client) {
if (client == exclude && client.key != key) return;
LOG("User already exist in array. Delete old socket");
client.emit('doExit');
});
}
function findAllSocketsByKey(key, excludeSocket){
var sockets = [];
clients.forEach(function (client) {
if (client == excludeSocket && client.key != key) return;
sockets.push(client);
});
return sockets;
}
function updateSocket(tempSocket){
clients[tempSocket.id] = tempSocket.socket;
}
// Send a message to all clients
function broadcast(message, sender) {
if (clients.length <= 0) return;
LOG('broadcast ' + message);
clients.forEach(function (client) {
// Don't want to send it to sender
if (client === sender) return;
client.write(message);
});
}
function packetMaker(userName, packetType, userMsg){
var p = {
currentTime: currentTime(),
chat: {
user: userName,
type: packetType
}
};
if (typeof userMsg != 'undefined')
p['chat']['msg'] = userMsg;
return 'ART|' + randomNumber(1000, 9000) + JSON.stringify(p) + '|AND';
}
});
tcpSocket.listen(5000, function(){
console.log('listening tcpSocket on port 5000');
cleanOnline();
});
function cleanOnline(){
console.log('Clean DB online');
//https.get('https://localhost/tgo/api/?apiCleanOnline');
}
function LOG(data){
console.log(currentTime() + " - " + data);
}
function randomNumber(min, max)
{
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function currentTime() {
var date = new Date();
var hour = date.getHours();
hour = (hour < 10 ? "0" : "") + hour;
var min = date.getMinutes();
min = (min < 10 ? "0" : "") + min;
var sec = date.getSeconds();
sec = (sec < 10 ? "0" : "") + sec;
var year = date.getFullYear();
var month = date.getMonth() + 1;
month = (month < 10 ? "0" : "") + month;
var day = date.getDate();
day = (day < 10 ? "0" : "") + day;
return year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec;
}
function findSocket(socket){
var socketData = {
'id': clients.indexOf(socket),
'socket': clients[clients.indexOf(socket)]
};
return socketData;
}