我正在尝试制作一个与母语使用者匹配的聊天应用程序(类似于Omegle.com)。我相信我有正确的算法,但我的Javascript不断发出Javascript heap out of memory
error的消息。
例如,假设Speaker 1
说English
并学习French
,Speaker 2
说French
并学习English
(完美匹配)。我的算法显示match found
。
队列控制器
socket.emit('in queue', {
speakingLanguages: speakingLanguages,
learningLanguages: learningLanguages
});
socket.on('chat start', function(data){
room = data.room;
$location.path('/chat');
});
server.js
var queue = [];
var rooms = {};
io.sockets.on('connection', function(socket){
console.log('User ' + socket.id + ' connected');
socket.on('in queue', function(data){
socket.speakingLanguages = data.speakingLanguages;
socket.learningLanguages = data.learningLanguages;
if (queue.length != 0){
for (var i = 0; i < queue.length; i++){
for (var j = 0; j < queue[i].speakingLanguages.length; j++){
for (var y = 0; y < socket.learningLanguages.length; y++){
if (queue[i].speakingLanguages[j] === socket.learningLanguages[y]){
console.log('a match was found!');
break;
}else{
queue.push(socket);
break;
}
}
}
}
}else{
queue.push(socket);
}
});
socket.on('send message', function(data){
var room = rooms[socket.id];
io.sockets.in(room).emit('send message', data);
});
});
但是看,当我在我的浏览器上打开多个窗口来测试很多情况时,我得到了上面的错误。它说我用尽Javascript heap
并且我一直在努力工作几个小时,但我不知道该怎么办。
信息:
speakingLanguages
和learningLanguages
属于数组(因为人们可以说多种语言并学习多种语言)queue
数组答案 0 :(得分:0)
我正在努力写下笔记并调查算法,我想我终于明白了。我测试了算法,它似乎正在工作!
socket.on('in queue', function(data){
socket.speakingLanguages = data.speakingLanguages;
socket.learningLanguages = data.learningLanguages;
var found = false;
if (queue.length != 0){
for (var i = 0; i < socket.learningLanguages.length; i++){
for (var j = 0; j < queue.length; j++){
for (var y = 0; y < queue[j].speakingLanguages.length; y++){
if (socket.learningLanguages[i] === queue[j].speakingLanguages[y]){
console.log('a match was found');
var peer = queue.pop();
var room = socket.id + '#' + peer.id;
peer.join(room);
socket.join(room);
rooms[peer.id] = room;
rooms[socket.id] = room;
peer.emit('chat start', { room: room });
socket.emit('chat start', { room : room });
found = true;
break;
}
}
}
}
if (!found){
queue.push(socket);
}
}else{
queue.push(socket);
}
});
答案 1 :(得分:0)
代码中有太多for
循环嵌套。
我对你的代码做了一些修改。
io.sockets.on('connection', function(socket){
console.log('User ' + socket.id + ' connected');
socket.on('in queue', function(data){
socket.speakingLanguages = data.speakingLanguages;
socket.learningLanguages = data.learningLanguages;
var searchingFor = [];
var toQueue = {};
var toUnqueue = {};
for (let spoken of socket.speakingLanguages) {
for (let learning of socket.learningLanguages) {
var searchKey = `S:${learning}L:${spoken}`;
var queueKey = `S:${spoken}L:${learning}`;
searchingFor.push(searchKey);
toQueue[queueKey] = socket;
toUnqueue[queueKey] = undefined;//Using `undefined` instead of `delete` for performance
}
}
//Search for a peer
var peer = false;//use an array[] if you want all matches
for (let searching of searchingFor) {
let result = queue[searching];
if(result) {
peer = result;
break;//You can change this part to find all matches
}
}
if (!peer) {
//No peer(s) found
//Add all possible combination of `spoken:learning` keys to the queue
//If someone searchs for one of these combinations we will be matched
socket.toUnqueue = toUnqueue;
Object.assign(queue, toQueue);
} else {
//We found a matching peer
console.log('a match was found');//If you use multiple matches you can ask what he prefers
//Unqueue other language combinations of the peer
Obeject.assign(queue, peer.toUnqueue);
//The rest of you logic goes here
var room = socket.id + '#' + peer.id;
peer.join(room);
socket.join(room);
rooms[peer.id] = room;
rooms[socket.id] = room;
peer.emit('chat start', { room: room });
socket.emit('chat start', { room : room });
}
});
socket.on('send message', function(data){
var room = rooms[socket.id];
io.sockets.in(room).emit('send message', data);
});
});
我改变了你使用队列的方式。
按键搜索应该更快
我没有测试它但它应该是好的。
告诉我它是否能完成这项工作!
答案 2 :(得分:0)
我使用amenzou的答案和另一个here
修改了我的代码var queue = [];
var rooms = {};
var index = 0;
var intersect_safe = function(a, b){
var ai=0, bi=0;
var result = [];
while( ai < a.length && bi < b.length )
{
if (a[ai] < b[bi] ){ ai++; }
else if (a[ai] > b[bi] ){ bi++; }
else /* they're equal */
{
result.push(a[ai]);
ai++;
bi++;
}
}
return result;
}
io.sockets.on('connection', function(socket){
console.log('User ' + socket.id + ' connected');
socket.on('in queue', function(data){
socket.speakingLanguages = data.speakingLanguages;
socket.learningLanguages = data.learningLanguages;
if (queue.length != 0){
for (var i = 0; i < queue.length; i++){
var match = false;
var match1 = [];
var match2 = [];
match1 = intersect_safe(socket.learningLanguages, queue[i].speakingLanguages);
match2 = intersect_safe(socket.speakingLanguages, queue[i].learningLanguages);
if (match1.length != 0 && match2.length != 0){
console.log('match');
index = i;
match = true;
break;
}
}
if (match){
var peer = queue.splice(index, 1);
var room = socket.id + '#' + peer[0].id;
peer[0].join(room);
socket.join(room);
rooms[peer[0].id] = room;
rooms[socket.id] = room;
peer[0].emit('chat start', match2);
socket.emit('chat start', match1);
}else{
queue.push(socket);
}
}else{
queue.push(socket);
}
});
完美的作品!非常感谢你的帮助和建议,amenzou。