在事件监听器内部管理逻辑; (我应该如何添加监听器?或者我应该使用条件“看门人”吗?)

时间:2016-04-01 22:31:32

标签: javascript node.js events express socket.io

我想知道控制与某些事件侦听器关联的逻辑是否处于活动状态的最佳方法。

我自然会遇到三种控制事件监听器内部逻辑的方法。

  1. 使用可作为门卫使用的所有连接套接字可访问的变量。如果一个套接字将变量设置为true,则所有套接字中的关联条件将允许运行其内部逻辑。类似地,如果一个套接字将变量设置为false,则没有套接字可以调用侦听器内的逻辑。情况1与其他两个不同,因为所有事件侦听器都是立即添加的(并且永远不需要删除)。
  2. 通过遍历套接字数组向所有套接字添加(或删除)事件侦听器。
  3. 使用app事件(被动地?)在所有套接字上添加(或删除)事件侦听器。
  4. (4.房间?我必须承认我根本没有使用过房间。但也许它们是适用的解决方案?)

    Visual Example

    Visual Representations of Ways of Controlling Logic in Event Listeners

    这是一个通用示例:

    index.js

        var express = require('express');
    var app = express();
    
    
    
    var fs = require('fs');
    
    var http = require('http').Server(app);
    
    
    
    
    
    
    
    var ioRequire = require('socket.io');
    var io = new ioRequire
    
    io.attach(http);
    
    startServingContent();
    handleSocketEvents();
    
    
    function startServingContent() {
    
      app.get('/', function(req, res){
        res.sendFile(__dirname + '/index.html');
      }); 
    
      var httpPort = 1337;
      http.listen(httpPort, function(){
        console.log('http server listening on ' + httpPort.toString());
      });
    }
    
    var runEvent2Code = false;
    
    function handleSocketEvents() {
      io.on('connection', function(socket) {
    
        logicGateExample();
    
        function logicGateExample() {
    
          socket.on('event1', function() {
            runEvent2Code = true;
          });
    
    
          socket.on('event2', function() {
            if (runEvent2Code) {
              console.log('event2 logic just ran');
            }
          });
        }
    
        dynamicallyAddEventListenersViaIterationExample();
    
        function dynamicallyAddEventListenersViaIterationExample() {
    
          socket.on('event3', function() {
    
            io.sockets.sockets.forEach(function(element, index, array) {
    
              element.on('event4', function() {
                console.log('event4 logic just ran');
              });
    
            });
    
          });
    
        }
    
        dynamicallyAddEventListenersViaAppExample();
    
        function dynamicallyAddEventListenersViaAppExample() {
          socket.on('event5', function() {
    
            app.emit('addEvent6 to all sockets');
    
    
    
          });
    
          app.on('addEvent6 to all sockets', function() {
              socket.on('event6', function() {
                console.log('event 6 logic just ran');
              });
    
          });
    
        }
    
      });
    }
    

    的index.html

    <script src="/socket.io/socket.io.js"></script>
    <script>
    
    
    
      var socket = io();
    
    
      handleThisClientEmits();
    
      function handleThisClientEmits() {
    
        // Won't trigger event logic because the event logic isn't "active".
        socket.emit('event2');
        // Won't trigger event logic because the event logic isn't "active".
        socket.emit('event4');
        // Won't trigger event logic because the event logic isn't "active".
        socket.emit('event6');
    
    
        socket.emit('event1');
        socket.emit('event2');
    
        socket.emit('event3');
        socket.emit('event4');
    
        socket.emit('event5');
        socket.emit('event6');
    
      }
    
    
    
    
    </script>
    

    节点命令提示符控制台输出:

    event2 logic just ran
    event4 logic just ran
    event6 logic just ran
    

    这是一个更具体的例子:

    我有一个游戏,用户登录后,特定用户启动游戏,新的事件监听器需要处理控制游戏的逻辑。因此,服务器注册用户的命令以启动游戏。它启动游戏逻辑并将适当的事件侦听器添加到客户端(或将适当的公共变量设置为true)。当游戏结束时,服务器删除适当的事件侦听器(或将适当的公共变量设置为false)。游戏逻辑的添加和删除/激活和停用可防止被黑客入侵游戏尚未启动时触发游戏事件,并帮助我在概念上将游戏与登录过程分开。

    同样,我问的最佳方法是什么? 或者一致性是否重要?如果最佳方法根据上下文的不同,我的游戏示例中的最佳方法是什么,以及其他有用的方法是什么?如果这些问题的答案都是意见问题,我很抱歉!

    使用app事件以及套接字事件似乎很奇怪和尴尬。使用迭代向所有套接字添加事件侦听器似乎更糟糕。但我记得被告知我的变量“看门人”方法并不反映node和socket.io的事件导向性质。

    (请参阅我的previous question以澄清最后一句。我觉得这个新问题更好地表达了我的担忧,并且是我正在处理的具体问题。)

    感谢您的帮助。我真的很感激!

    请原谅我对术语的憎恶和误用,以及我缺乏简洁性。

1 个答案:

答案 0 :(得分:1)

Number 1,一个全局(或每个房间)状态变量,比尝试继续添加和删除事件处理程序更简单。此外,您可能不需要像您认为的那样多的不同类型的事件。 Socket.io客户端可以根据事件类型发送具有不同参数的消息。所以这也可以简化一些事情。

就防止客户作弊而言,这是一个完全不同的蠕虫病毒,如果你真的担心这一点,那么你可能需要花费大量时间来研究解决方案。