socket-io - 匹配学习和口语

时间:2017-08-06 05:39:13

标签: angularjs node.js socket.io

我正在尝试制作一个与母语使用者匹配的聊天应用程序(类似于Omegle.com)。我相信我有正确的算法,但我的Javascript不断发出Javascript heap out of memory error的消息。

例如,假设Speaker 1English并学习FrenchSpeaker 2French并学习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并且我一直在努力工作几个小时,但我不知道该怎么办。

信息:

  • speakingLanguageslearningLanguages属于数组(因为人们可以说多种语言并学习多种语言)
  • 每次找不到匹配项时,我都会将它们放入queue数组

3 个答案:

答案 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。