【问题标题】:socket-io - matching learning and speaking languagessocket-io - 匹配学习和口语
【发布时间】:2018-01-13 16:45:41
【问题描述】:

我正在尝试制作一个聊天应用程序(类似于 Omegle.com),它将母语人士与学习者相匹配。我相信我有正确的算法,但我的 Javascript 不断抛出一条消息,Javascript heap out of memoryerror

例如,假设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,我已经为此苦苦挣扎了好几个小时,但我不知道该怎么办。

信息:

  • speakingLanguageslearningLanguagesarray 类型(因为人们可以说多种语言并学习多种语言)
  • 每次找不到匹配的时候,我把它们放到queue数组中

【问题讨论】:

    标签: angularjs node.js socket.io


    【解决方案1】:

    我使用 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。

    【讨论】:

      【解决方案2】:

      您的代码中有太多的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);
        });
      });
      

      我改变了你使用队列的方式。 按键搜索应该更快。
      我没有测试它,但它应该很好。
      告诉我它是否有效!

      【讨论】:

      • 非常感谢这个改进的算法。给我时间把它放在我的代码中,我会尽快与您联系!非常感谢你为我做这件事,amenzou
      • 嘿,请您澄清一下“availableKey”到底是什么?我假设它只是“socket.id”?当我运行它时,我也收到“peer.emit 不是函数”错误。我会更多地研究这个算法,看看我能不能想出什么。感谢您的帮助!
      • 对不起,我把availableKey的名字改成了queueKey,忘了到处改。 learning 这个词也有一个错字。现在应该可以工作了。我编辑了代码。对等体是套接字。
      • @Student22 你有时间测试我所做的更正吗?
      • 是的!我在这里写了一个新的答案。感谢您的帮助!
      【解决方案3】:

      我一直在努力写下笔记并研究算法,我想我终于明白了。我测试了算法,它似乎可以工作!

      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);
          }
      });
      

      【讨论】:

        猜你喜欢
        • 2017-07-06
        • 2011-10-04
        • 1970-01-01
        • 2019-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-24
        相关资源
        最近更新 更多