Difference between Events and Functions? - javascript

I am new to Node, and I am struggling to understand the main difference between Events and Functions. Both need to be triggered, so why do we need an Event at all if we have to trigger it anyway?
How is it different than having a Function triggered?
Example code:
var events = require('events');
var eventEmitter = new events.EventEmitter();
eventEmitter.on('event1', function () {
console.log('Event 1 executed.');
eventEmitter.emit('event2');
});
eventEmitter.on('event2', function() {
console.log('Event 2 executed.');
});
eventEmitter.emit('event1');
console.log('Program Ended.');
We can achieve the same result by functions, right?
I am sure this has some serious importance in Node (otherwise it would not exist, lol), but I am struggling to understand it.
Help appreciated! :)

Events deal with asynchronous operations. They aren't really related to functions in the sense that they are interchangeable.
eventEmitter.on is itself a function, it takes two arguments the event name, then a function (callback) to be executed when the event happens.
eventEmitter.on(evt, callback)
There is no way to tell WHEN the event will be emitted, so you provide a callback to be executed when the event occurs.
In your examples, you are controlling when the events are triggered, which is different than real world use where you may have a server listening for connections that could connect at anytime.
server.listen('9000', function(){
console.log('Server started');
});
server.on('connection', function(client){
console.log('New client connected');
doSomethingWithClient(client);
});
//series of synchronous events
function doSomethingWithClient(client){
//something with client
}
For server.listen the server doesn't start immediately, once its ready the callback is called
server.on('connection') listens for client connections, they can come at any time. The event is then triggered when a connection occurs, causing the callback to be run.
Then there is doSomethingWithClient this is just a function with a set of synchronous operations to be done when a client connection occurs.

Events useful in webserver code (that is active on port) not in normal scripts, in normal scripts events will behave same as functions because events will be continually active & listening on port for requests as long as port is up so if we use function instead, function will run only once when .js file is ran thus functions cannot capture incoming request and respond.
Example
In this code if you see output of below function dummy_func() triggered immediately when js file is ran & printed statement ConditionReport: A client Connected: 0 only once as output,
but the EventReport: A client Connected: printed only when opened http://localhost:58080 in browser and again in another tab if I open same http://localhost:58080 it printed again EventReport: A client Connected: 3
const express = require('express');
const app = express();
const path = require('path');
const PORT = process.env.PORT || 58080;
// Load all static html files in the directory, here index.html file open as default at http://localhost:58080/ but to load html like Resume.html we should call complete http://localhost:58080/Resume.html
app.use(express.static(path.join(__dirname)));
// Configure Port
var server_object=app.listen(PORT, () => console.log("Server listening on port " + PORT));
//Possible incoming Events
var incoming_events=server_object.eventNames()
console.log("\nserver_object:", incoming_events);
//On Event
var i=0
server_object.on('connection',()=>{
i=i+1
console.log("\nEventReport: A client Connected:",i);
});
//Using if condition instead of Event
function dummy_func(j){
console.log("\nConditionReport: A client Connected:",j,"\n");
}
var j=0
if (incoming_events.includes('connection')){
dummy_func(j)
j=j+1
}
OUTPUT:
stataraju#statara-ltm7wjr Example2 % node index.js
server_object: [ 'request', 'connection', 'listening' ]
ConditionReport: A client Connected: 0
Server listening on port 58080
EventReport: A client Connected: 1
EventReport: A client Connected: 2
EventReport: A client Connected: 3

I suppose I see the biggest difference I see is that an event emitter could trigger multiple events that are listening, whereas just calling a function only triggers one thing.
So for example, you could have numerous objects in a game that are all waiting for a step event that increments their animation.
They are such a pain to debug though that I'd much rather just use functions.

An event is an identifier used within tools (.on(), .emit() etc) to set and execute callbacks. Functions are reusable code.

Related

clientside nodejs readline not triggering 'close' event except on CTRL-C from server

I am trying to make a simple server/client TCP connection with javascript using nodejs.
I have client.js code (which I can't modify) which has this line:
var s = net.connect({port: this._port}),
rl = readline.createInterface({input: s});
s.write('quit\r\n');
rl.on('close', () => done(null, output));
The problem is, I cannot get that event to trigger. On the server side, I have
socket.once("close", function () {
console.log("Connection from %s closed", remoteAddress);
// socket.destroy();
});
socket.once("end", function() {
console.log("Ending connection");
// socket.destroy();
})
The server side receives an end event, and prints it out, followed by the close. However, I can't seem to get that client to get that end event naturally. Something weird that does work though, is if I CTRL+C the server and stop it midway. That causes the client to get the 'end' and move on with the code. As of now, it just timeouts. Now I am wondering if it's possible to automatically send a CTRL+C or if there is any other way to get this 'end' to trigger.
Methods I have tried:
socket.destroy(), sending EOT character.
Again, I cannot modify this client.js.

What is the purpose of custom eventemitters in node.js? [duplicate]

I am new to Node, and I am struggling to understand the main difference between Events and Functions. Both need to be triggered, so why do we need an Event at all if we have to trigger it anyway?
How is it different than having a Function triggered?
Example code:
var events = require('events');
var eventEmitter = new events.EventEmitter();
eventEmitter.on('event1', function () {
console.log('Event 1 executed.');
eventEmitter.emit('event2');
});
eventEmitter.on('event2', function() {
console.log('Event 2 executed.');
});
eventEmitter.emit('event1');
console.log('Program Ended.');
We can achieve the same result by functions, right?
I am sure this has some serious importance in Node (otherwise it would not exist, lol), but I am struggling to understand it.
Help appreciated! :)
Events deal with asynchronous operations. They aren't really related to functions in the sense that they are interchangeable.
eventEmitter.on is itself a function, it takes two arguments the event name, then a function (callback) to be executed when the event happens.
eventEmitter.on(evt, callback)
There is no way to tell WHEN the event will be emitted, so you provide a callback to be executed when the event occurs.
In your examples, you are controlling when the events are triggered, which is different than real world use where you may have a server listening for connections that could connect at anytime.
server.listen('9000', function(){
console.log('Server started');
});
server.on('connection', function(client){
console.log('New client connected');
doSomethingWithClient(client);
});
//series of synchronous events
function doSomethingWithClient(client){
//something with client
}
For server.listen the server doesn't start immediately, once its ready the callback is called
server.on('connection') listens for client connections, they can come at any time. The event is then triggered when a connection occurs, causing the callback to be run.
Then there is doSomethingWithClient this is just a function with a set of synchronous operations to be done when a client connection occurs.
Events useful in webserver code (that is active on port) not in normal scripts, in normal scripts events will behave same as functions because events will be continually active & listening on port for requests as long as port is up so if we use function instead, function will run only once when .js file is ran thus functions cannot capture incoming request and respond.
Example
In this code if you see output of below function dummy_func() triggered immediately when js file is ran & printed statement ConditionReport: A client Connected: 0 only once as output,
but the EventReport: A client Connected: printed only when opened http://localhost:58080 in browser and again in another tab if I open same http://localhost:58080 it printed again EventReport: A client Connected: 3
const express = require('express');
const app = express();
const path = require('path');
const PORT = process.env.PORT || 58080;
// Load all static html files in the directory, here index.html file open as default at http://localhost:58080/ but to load html like Resume.html we should call complete http://localhost:58080/Resume.html
app.use(express.static(path.join(__dirname)));
// Configure Port
var server_object=app.listen(PORT, () => console.log("Server listening on port " + PORT));
//Possible incoming Events
var incoming_events=server_object.eventNames()
console.log("\nserver_object:", incoming_events);
//On Event
var i=0
server_object.on('connection',()=>{
i=i+1
console.log("\nEventReport: A client Connected:",i);
});
//Using if condition instead of Event
function dummy_func(j){
console.log("\nConditionReport: A client Connected:",j,"\n");
}
var j=0
if (incoming_events.includes('connection')){
dummy_func(j)
j=j+1
}
OUTPUT:
stataraju#statara-ltm7wjr Example2 % node index.js
server_object: [ 'request', 'connection', 'listening' ]
ConditionReport: A client Connected: 0
Server listening on port 58080
EventReport: A client Connected: 1
EventReport: A client Connected: 2
EventReport: A client Connected: 3
I suppose I see the biggest difference I see is that an event emitter could trigger multiple events that are listening, whereas just calling a function only triggers one thing.
So for example, you could have numerous objects in a game that are all waiting for a step event that increments their animation.
They are such a pain to debug though that I'd much rather just use functions.
An event is an identifier used within tools (.on(), .emit() etc) to set and execute callbacks. Functions are reusable code.

Why does my socket.io app disconnect immediately when run on Raspberry pi?

I am attempting to build a node.js application on a Raspberry Pi which can communicate with a remote socket.io server.
The socket.io server quite simply writes to the console when a new connection is established and when an existing connection is closed.
The socket.io client works as expected when run in a browser.
However, when I run the client code from a Raspberry Pi it connects and immediately terminates. This does not allow me to perform any function such as emitting or receiving.
The on connect event is never fired.
var io = require('/usr/local/lib/node_modules/socket.io-client');
var serverUrl = 'http://remoteserver.com';
console.log('Connecting to ' + serverUrl);
var socket = io.connect(serverUrl);
socket.on('connect', function(socket) {
console.log('Connection established!');
console.log(socket.id);
socket.on('disconnect', function() {
console.log('Disconnected from server');
});
});
The code above will output:
Connecting to: http://remoteserver.com
On the server side, the output will show a new connection and eventually a timeout close.
Why is the client on connect event not firing? How can I persist this connection so that I can eventually send inputs to the server?
Remove the line:
socket.close();
from your code. You are closing the socket immediately. Remember that all the event handlers are asynchronous. They are non-blocking and will be called some time in the future. Meanwhile, the rest of your code runs to completion and thus your socket.close() is executed before your client has any chance to get any events (other than the disconnect event).
If you want to do some stuff and then close the socket, then you need to close the socket only from some event handler that indicates that your operation is complete and you are now done with the socket.
You only need to call socket.close() when you want to close the connection from the raspberry pi. Also, the socket.io-client documentation does not use the .connect method, but instead calls require('socket.io-client')(serverUrl)
var io = require('/usr/local/lib/node_modules/socket.io-client');
var serverUrl = 'http://remoteserver.com';
console.log('Connecting to ' + serverUrl);
var socket = io(serverUrl);
socket.on('connect', function(socket) {
console.log('Connection established!');
console.log(socket.id);
});
socket.on('disconnect', function() {
console.log('Disconnected from server');
});
//Removed the socket.close() line

How to call a function when node server is up?

I want to call a function when the net.serverCreate is up. It need to call this function when the server is started and not when a new connection appears. Event 'listening' dont fire...When I start the server I want to check something in Mysql data-base... How to execute functions when server starts?
My app:
var server = net.createServer(function (socket) {
socket.on('listening', function () {
console.log("Console is listening! "); //Its dont log
});
socket.on('data', function (message) {
});
socket.on('end', function () {
socket.end();
});
});
server.listen(1337,function(){
console.log("Server starts succefully"); //Its working!
});
Event 'listening' dont fire
The callback to createServer is handed a client Socket. Client-side sockets don't listen for requests; they make requests. So a listening event is never emitted by Sockets
On the other hand, net.createServer() returns a server-side socket(similar to Java's ServerSocket)
This should work.
server.listen(1337,function(){
//mysql db query
});
The callback to listen is executed when the server is bound to the specified port, i.e., when the server starts listening. The last parameter to listen is added as a listener for the listening event.
Another way to monitor the server-start event is:
server.on('listening', function() {
//mysql db query
});
Listening event

Socket.io with Cluster: iterating over all open connections

I'm running Socket.io multi-threaded with the native cluster functionality provided by Node.js v0.6.0 and later (with RedisStore).
For every new change in state, the server iterates over each connection and sends a message if appropriate. Note: this isn't "broadcasting" to all connections, it's comparing server data with data the client sent on connection to decide whether to send the server data to that particular client. Consider this code sample:
io.sockets.clients().forEach(function (socket) {
socket.get('subscription', function (err, message) {
if(message.someProperty === someServerData) {
socket.emit('position', someServerData);
}
});
This worked fine when there was only one process, but now, the client receives a message for each Node process (ie. if there are 8 Node process running, all clients receive the messages 8 times).
I understand why the issue arises, but I'm not sure of a fix. How can I assign a 1-to-1 relation from one process to only on client. Perhaps something using NODE_WORKER_ID of Cluster?
This previous SO question seems somewhat related, although I'm not sure it's helpful.
This seems like a pretty common request. Surely, I must be missing something?
So if I get this straight you need to emit custom events from the server. You can do that by creating your own custom EventEmitter and triggering events on that emitter, for example:
var io = require('socket.io').listen(80);
events = require('events'),
customEventEmitter = new events.EventEmitter();
io.sockets.on('connection', function (socket) {
// here you handle what happens on the 'positionUpdate' event
// which will be triggered by the server later on
eventEmitter.on('positionUpdate', function (data) {
// here you have a function that checks if a condition between
// the socket connected and your data set as a param is met
if (condition(data,socket)) {
// send a message to each connected socket
// if the condition is met
socket.emit('the new position is...');
}
});
});
// sometime in the future the server will emit one or more positionUpdate events
customEventEmitter.emit('positionUpdate', data);
Another solution would be to have those users join the 'AWE150', so only they will receive updates for 'AWE150', like so:
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
if (client_is_interested_in_AWE) { socket.join('AWE150'); }
io.sockets.in('AWE150').emit('new position here');
});
Resources:
http://spiritconsulting.com.ar/fedex/2010/11/events-with-jquery-nodejs-and-socket-io/

Categories

Resources