I want to know the best way to control whether logic associated with certain event listeners is active.
I have naturally come across three ways of controlling the logic inside event listeners.
- Using a variable accessible by all connected sockets that acts as a gate keeper. If one socket sets the variable to true then the associated conditional in all sockets will allow the its internal logic to be ran. Similarly, if one socket sets the variable to false no sockets can invoke the logic inside the listener. Case 1 is different from the other two in that all event listeners are added immediately (and never need be removed).
- Adding (or removing) event listeners to all sockets by iterating through the array of sockets.
- Using app events to (passively?) add (or remove) event listeners on all sockets.
(4. Rooms? I must confess I'm haven't used rooms at all. But maybe they are an applicable solution? )
Visual Example
Here is a generic example:
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>
Node Command Prompt Console Output:
event2 logic just ran
event4 logic just ran
event6 logic just ran
Here's a more specific example:
I have a game where after users log in and a specific user starts the game, new event listeners need to handle the logic that controls the game. So the server registers a user's command to start game. It starts up the game logic and adds the appropriate event listeners to the clients (or sets the appropriate common variable to true). When the game ends the server removes the appropriate event listeners (or sets the appropriate common variables to false). The adding and removing / activating and disactivating of game logic prevents hacked clients from triggering game events when the game hasn't even started yet and helps me conceptually separate the game from the login process.
Again, I'm asking what is the best method to use? Or is consistency simply important? If the best method differs depending on the context what is the best method in my game example and what are the other methods useful for? If the answers to these questions are all a matter of opinion, I'm sorry!
Using app events as well as socket events seems weird and awkward. Using iteration to add event listeners to all the sockets seems even worse. But I remember being told that my variable "gatekeeper" approach doesn't reflect the event oriented nature of node and socket.io.
(See my previous question for clarification of the last sentence. I feel this new question expresses my concerns better and a specific problem I'm dealing with.)
Thanks for any help. I really appreciate it!
Please forgive my abhorrent knowledge of and misuse of terminology, and my lack of succinctness.