【发布时间】:2016-01-20 11:05:38
【问题描述】:
我正在尝试构建一个简单的系统,将某些详细信息附加到客户,例如昵称、国家/地区等,但我偶然发现了有关信息未正确注册的问题。
请看我的代码:
index.js
var express = require('express'),
app = express(),
server = require('http').Server(app),
io = require('socket.io')(server),
glob = require('glob'),
path = require('path'),
fs = require('fs'),
satelize = require('satelize');
var chat = require(__dirname + '/inc/chat');
server.listen(8888);
app.use('/public', express.static(path.join(__dirname, 'public')));
app.get('/', function (req, res) {
res.sendFile(__dirname + '/views/index.html');
});
io.on('connection', function (socket) {
chat.init(satelize,socket, function () {
var client = chat.fetchClient(socket.id);
socket.emit('client info', client);
socket.on('message', function (msg) {
console.log('Message recieved from ' + client.id);
socket.emit('client info', client);
});
socket.on('disconnect', function () {
chat.removeClient(client);
});
});
});
/inc/chat.js
module.exports = {
/* client object initialization */
client : {
id : null,
username : null,
geo : null
},
/* client array initialization */
clients: [],
init: function (satelize, socket, callback) {
var init = this;
if (typeof callback == "function") {
var client = this.client;
client.id = socket.id;
satelize.satelize( { ip : this.ip(socket ) }, function(error, payload) {
client.geo = payload;
init.addClient(client);
callback();
});
}
},
/* information retrieval*/
ip: function (socket) {
return cleanIp(socket.handshake.address)
},
/* client (the user) stuff */
addClient: function (client) {
if (client.id !== null) {
this.clients.push(client);
console.log(client.id + ' added to clients.');
} else {
console.log('Cannot add client: id (null)');
}
},
fetchClient: function (id) {
for (var i = 0; i < this.clients.length; i++) {
if(this.clients[i].id == id) {
return this.clients[i];
}
}
},
removeClient: function (client) {
console.log('removing client: ');
console.log(client.id);
var found = null;
for (var i = 0; i < this.clients.length; i++) {
if (this.clients[i] == client) {
this.clients.splice(i,1);
found = this.clients[i];
break;
}
}
if (this.clients.length > 0) {
console.log('client list after removal: ');
for (var i = 0; i < this.clients.length; i++) {
console.log(this.clients[i].id);
}
} else {
console.log('No clients in client array.');
}
}
}
function cleanIp (ip) {
return ip.replace('::ffff:','');
}
在 index.html 中,我有以下 js 用于 id 和消息的可视化表示:
var socket = io();
socket.on('client info', function (data) {
$('.client-id').text(data.id);
});
$('#input').keydown(function(e) {
var key = e.which;
if (key == 13) {
if ($(this).val().length > 0) {
socket.emit('message', $(this).val());
$(this).val('');
}
}
});
好的,如果我启动这个简单的节点服务器并在三个不同的浏览器选项卡中打开页面而不发送任何消息,那么 id 似乎是正确的。
但只要我从其中一个浏览器选项卡发送消息,它就会采用最后连接的客户端 ID。
当服务器启动时,它会在控制台中输出以下内容:
[nodemon] starting `node index.js`
/#h9sraEo5c8uLKgczAAAA added to clients.
/#opAfZCrRa64gFsR7AAAB added to clients.
/#x-WfhClfNsLEWE85AAAC added to clients.
如果我刷新第一个标签:
removing client:
/#x-WfhClfNsLEWE85AAAC
client list after removal:
/#x-WfhClfNsLEWE85AAAC
/#x-WfhClfNsLEWE85AAAC
/#pdlKD-v3K15_2voZAAAD added to clients.
如果我从该选项卡发送消息:
Message recieved from /#pdlKD-v3K15_2voZAAAD
如果我现在切换到另一个选项卡并写一条消息,服务器会输出与上面相同的消息,并更改浏览器中 id 的视觉表示。
为什么连接的客户端的id会变成最后连接的客户端的id?
【问题讨论】:
标签: javascript node.js socket.io