duplicates in socket.io w/ angular - javascript

Using angular and socket.io I am getting duplicate events on the client everytime the server emits. Angular is only included once, there is only one socket.io connection, and there is only one listener per event on the client. Upon receiving an event on the server, data is logged, and this process only ever happens once. Then the data is emitted and the callback is called twice on the client, despite only being in scope once(to my knowledge).
client:
//inside a controller
var thing ='foo';
socket.emit('sentUp',thing)
socket.on('sentDown',function(thing){
console.log(thing)//this happens twice
});
server:
/*
node&express stuff here
*/
socket.on('connection',function(socket){
socket.on('sentUp',function(stuff){
console.log('this happened')//x1
socket.emit('sendDown',stuff);
});
})

Most likely your controllers are being loaded more than once. You can easily check it by logging.
Move out the socket code from the controllers and put them in a service where they're only called once.

I have found in my own socket.io client code that some of the connect events can occur each time the client reconnects. So, if the connected is lost for any reason and then the client automatically reconnects, the client may get a connect event again.
If, like me, you're adding your event handlers in the 'connect' event, then you may be accidentially adding multiple event handlers for the same event and thus you would think you were seeing duplicate data. You don't show that part of your client code so I don't know you're doing it that way, but this is an issue that hit me and it is a natural way to do things.
If that is what is happening to you, there are a couple possible work-arounds:
You can add your event handlers outside the connect event. You don't have to wait for connection to finish before adding event handlers. This way, you'd only ever do them once.
Before adding the event handlers you add upon connection, you can remove any previous event handlers that were installed upon connection to make sure you never get dups.

Related

What happens when an onCreate event happens again while another Firebase function is already running?

Background
I have a Firebase Cloud Function which sometimes can take a while to complete (20-60 seconds).
It gets triggered by a write to Firebase, which means that it starts processing at the onCreate event.
Problem
I have been doing some scripted testing by creating a new record in Firebase every N seconds, but it seems that if N is less than 20 seconds, the next onCreate trigger just doesn't fire.
In other words I end up in a situation like this:
Firebase:
record1
record2
record3
record4
Results written by the triggered function to another node in Firebase:
result-from-record1
...
record2, record3, record4 does not seem to trigger the function again.
Homework
I have re-checked Firebase documentation, but I cannot seem to find any information that explains this case.
There is some information about quotas for connected users, but it's only about connected users, not about the same triggers firing many times before the previously triggered function completes.
Questions
What is the default behavior of Firebase triggered functions in case it gets triggered while the previously triggered function is still running?
Is there any way to maybe cancel the running function if it gets triggered by a new onWrite?
Is there any queue of those triggered and running functions? (this queue doesn't seem to be the one)
What is the default behavior of Firebase triggered functions in case it gets triggered while the previously triggered function is still running?
There is no guarantee about how functions are invoked - they could happen in sequence on a single server instance, or they could run in run in parallel on multiple server instances. The order of invocation of functions is also not guaranteed.
Is there any way to maybe cancel the running function if it gets triggered by a new onWrite?
No.
Is there any queue of those triggered and running functions? (this queue doesn't seem to be the one)
There is no visible queue. Internally, Cloud Functions is using pubsub to manage the stream of events emitted by the database, but this is an implementation detail, and you have no direct control over how it works.
As for why your function doesn't seem to execute when you expect - there's not enough detail in your question to make a guess. Without seeing actual code, as well as the specific steps to take to reproduce the issue, it's not possible to say.
You might want to watch my video series on how Cloud Functions works in order to better understand its behavior.

Debugging why socket.on is not being hit

This issue is occurring on the client side of my application.
I am running into a issue with the socket.on event not being hit on my Node application. This usually happens when the site is being loaded for the first time by a client. When loading, the tabs usually have the data which has been dynamically generated in Javascript, however since the socket.on event is not being hit this content is not loading, leading to the tabs being blank (The base Pug/Jade file is still rendering - just no dynamic content). Refreshing the page usually fixes the issue and the sockets start receiving the data again.
There is no direct error message being output, the socket.on event is just not being hit. This also seems to solve itself once the page has been reloaded and is not occurring 100% of the time.
This is even more unusual, as when running my Node server in debug mode it is showing the socket.io-parser encoding the data and socket.io-client writing the data, meaning that it is being emitted, just not being picked up by the socket.on on my client side.
Note that this has been simplified down
io.sockets.on('connection', function (client) {
sendExampleData();
});
function sendExampleData() {
mysqlFunc.getOrderData(function(rows){
io.emit('example_data', rows);
})
}
socket.on('example_data', function (rows) {
console.log(rows);
}
I expect that on page load, the data is emitted and the socket.on event will receive this data, ready to be processed. Currently, although not happening every-time, socket.on is not being hit and the data is not being grabbed.
There is nothing out of the ordinary whilst running the server in Debugging mode and any ideas would be extremely helpful. If there's any other bits of information that would be useful in helping debug this issue please let me know.
Thanks in advance!
I finally managed to figure out what the issue was.
My socket.on event listeners were inside my $(document).ready and were not being called on first page load. I'm assuming that the event listeners were not being defined early enough and therefore when I socket.emit'd on connection the event listeners had not actually loaded.
I moved all of the logic which was inside the $(document).ready out and moved my event listeners into a connection event (Thanks for the tip Marc).
socket.on('connect', function(){
socket.on('data_1', funcOne);
socket.on('data_2', funcTwo);
socket.on('data_3', funcThree);
socket.on('data_4', funcFour);
socket.on('data_5', funcFive);
});
This fixed the issue and now socket.on is being hit every time on page load.
Thanks for the help guys and hopefully this can help someone also having this issue!

Node JS Asynchronous Execution and Event Emission / Listener Models

I am new to Node JS and am trying to understand the concurrent / asynchronous execution models of Node.
So far, I do understand that whenever an asynchronous task is encountered in Node, that task runs in the background ( e.g an asynchronous setTimeout function will start timing) and the control is then sent back to other tasks that are there on the call stack. Once the timer times out, the callback that was passed to the asynchronous task is pushed onto the callback queue and once the call stack is empty, that callback gets executed. I took the help of this visualization to understand the sequence of task execution. So far so good.
Q1. Now, I am not being able to wrap my head around the paradigm of event listeners and event emitters and would appreciate if someone could explain how even emitters and listeners fall into the picture of call stack, event loops and callback queues.
Q2. I have the following code that reads data from the serial port of a raspberry pi.
const SerialPort = require('serialport');
const port = new SerialPort('/dev/ttyUSB0',{baudRate: 9600}, (err) => {
if (err) {
console.log("Port Open Error: ", err);
}
} )
port.on('data', (data) => {
console.log(data.toString());
})
As can be seen from the example, to read data from the serial port, an 'event-listener' has been employed. From what I understand, whenever data comes to the port, a 'data' event is emitted which is 'responded to' or rather listened to by the listener, which just prints the data onto the console.
When I run the above program, it runs continuously, with no break, printing the data onto the console whenever a data arrives at the serial port. There are no continuously running while loops continuously scanning the serial port as would be expected in a synchronous program. So my question is, why is this program running continuously? It is obvious that the event emitter is running continuously, generating an event whenever data comes, and the event listener is also running continuously, printing the data whenever a 'data' event is emitted. But WHERE are these things actually running, that too, continuously? How are these things fitting into the whole picture of the call/execution stack, the event loop and the callback queue?
Thanks
Q1. Now, I am not being able to wrap my head around the paradigm of event listeners and event emitters and would appreciate if someone could explain how even emitters and listeners fall into the picture of call stack, event loops and callback queues.
Event emitters on their own have nothing to do with the event loop. Event listeners are called synchronously whenever someone emits an event. When some code calls someEmitter.emit(...), all listeners are called synchronously from the time the .emit() occurred one after another. This is just plain old function calls. You can look in the eventEmitter code yourself to see a for loop that calls all the listeners one after another associated with a given event.
Q2. I have the following code that reads data from the serial port of a raspberry pi.
The data event in your code is an asynchronous event. That means that it will be triggered one or more times at an unknown time in the future. Some lower level code will be registered for some sort of I/O event. If that code is native code, then it will insert a callback into the node.js event queue. When node.js is done running other code, it will grab the next event from the event queue. When it gets to the event associated with data being available on the serial port, it will call port.emit(...) and that will synchronously trigger each of the listeners for the data event to be called.
When I run the above program, it runs continuously, with no break, printing the data onto the console whenever a data arrives at the serial port. There are no continuously running while loops continuously scanning the serial port as would be expected in a synchronous program. So my question is, why is this program running continuously?
This is the event-driven nature of node.js in a nutshell. You register an interest in certain events. Lower level code sees that incoming data has arrived and triggers those events, thus calling your listeners.
This is how the Javascript interpreter manages the event loop. Run current piece of Javascript until it's done. Check to see if any more events in the event loop. If so, grab next event and run it. If not, wait until there is an event in the event queue and then run it.
It is obvious that the event emitter is running continuously, generating an event whenever data comes, and the event listener is also running continuously, printing the data whenever a 'data' event is emitted. But WHERE are these things actually running, that too, continuously?
The event emitter itself is not running continuously. It's just a notification scheme (essentially a publish/subscribe model) where one party can register an interest in certain events with .on() and another party can trigger certain events with .emit(). It allows very loose coupling through a generic interface. Nothing is running continuously in the emitter system. It's just a notification scheme. Someone triggers an event with .emit() and it looks in its data structures to see who has registered an interest in that event and calls them. It knows nothing about the event or the data itself or how it was triggered. The emitters job is just to deliver notifications to those who expressed an interest.
We've described so far how the Javascript side of things works. It runs the event loop as described above. At a lower level, there is serial port code that interfaces directly with the serial port and this is likely some native code. If the OS supports a native asynchronous interface for the serial port, then the native code would use that and tell the OS to call it when there's data waiting on the serial port. If there is not a native asynchronous interface for the serial port data in the OS, then there's probably a native thread in the native code that interfaces with the serial port that handles getting data from the port, either polling for it or using some other mechanism built into the hardware to tell you when data is available. The exact details of how that works would be built into the serial port module you're using.
How are these things fitting into the whole picture of the call/execution stack, the event loop and the callback queue?
The call/execution stack comes into play the moment an event in the Javascript event queue is found by the interpreter and it starts to execute it. Executing that event will always start with a Javascript callback. The interpreter will call that callback (putting a return address on the call/execution stack). That callback will run until it returns. When it returns, the call/execution stack will be empty. The interpreter will then check to see if there's another event waiting in the event queue. If so, it will run that one.
FYI, if you want to examine the code for the serial port module it appears you are using, it's all there on Github. It does appear to have a number of native code files. You can see a file called poller.cpp here and it appears to do cooperative polling using the node.js add-on programming interface offered by libuv. For example, it creates a uv_poll_t which is a poll handle described here. Here's an excerpt from that doc:
Poll handles are used to watch file descriptors for readability, writability and disconnection similar to the purpose of poll(2).
The purpose of poll handles is to enable integrating external libraries that rely on the event loop to signal it about the socket status changes, like c-ares or libssh2. Using uv_poll_t for any other purpose is not recommended; uv_tcp_t, uv_udp_t, etc. provide an implementation that is faster and more scalable than what can be achieved with uv_poll_t, especially on Windows.
It is possible that poll handles occasionally signal that a file descriptor is readable or writable even when it isn’t. The user should therefore always be prepared to handle EAGAIN or equivalent when it attempts to read from or write to the fd.

How can I guarantee that websocket onopen to be called

I use WebSocket in javascript. WebSocket requires the url as constructor parameter and immediately try to connect. I can set onopen method only after construct it.
So, if WebSocket already establishes the connection before I set onopen, then I miss onopen event!
How can I avoid this?
To simulate it:
A)
1) In Chrome, open websocket.
2) Press F12 to open Developer Tools.
3) Open Console
4) Copy and paste all of these codes at once! Enter!
uri = "ws://echo.websocket.org?encoding=text";
websocket = new WebSocket(uri);
websocket.onopen = function(evt) { console.log('EHE')};
B)
Repeat 1-2-3
4) Copy and paste these codes and run
uri = "ws://echo.websocket.org?encoding=text";
websocket = new WebSocket(uri);
5) Wait a second
6) Run this code:
websocket.onopen = function(evt) { console.log('EHE')};
Result:
In A) onopen is called. In B) we missed it!
Because of the single-threaded event driven nature of Javascript, what you describe will not happen in real code. The "open" event can't be triggered until after your current section of Javascript finishes. Thus, you will always be able to set your onopen event handler before the event occurs.
Inserting artificial pauses in the debugger or in the console is an artificial situation that does not occur in real code.
What happens in real code is this:
You call new WebSocket(uri)
The webSocket intrastructure initiates a webSocket connection (an asynchronous operation)
The webSocket constructor returns immediately before that connection has completed.
The rest of your code runs (including assigning the .onopen property and setting up your event handler.
The Javascript interpreter is done running your code and returns back to the event loop.
If, by now, the webSocket has connected, then there will be an open event in the event queue and Javascript will trigger that event, resulting in your .onopen handler getting called.
If the open event has not yet completed, Javascript will wait for the next event to be inserted into the event queue and will run it, repeating that process over and over. Eventually one of these events will be your open event.
The key to this is that .onopen is called via an asynchronous event. Thus, it has to go through the Javascript event queue. And, no events from the event queue can be run until after your current section of Javascript finishes and returns back to the interpreter. That's how the "event-driven" nature of Javascript works. So, because of that architecture, you cannot miss the onopen event as long as you install your .onopen handler in the same section of Javascript that calls the constructor.
If it provides you any comfort, there are dozens of APIs in node.js that all rely on this same concept. For example when you create a file stream with fs.createReadStream(filename), you have to create the stream, then add event handlers (one of those event handlers is for an open event). The same logic applies there. Because of the event-driven nature of Javascript, there is no race condition. The open event or the error event cannot be triggered before the rest of your Javascript runs so you always have an opportunity to get your event handlers installed before they could get called.
In cases where errors could be detected synchronously (like a bad filename or bad uri) and could trigger an error event immediately, then code using something like setImmediate(function() { /* send error event here*/ }) to make sure the error event is not triggered until after your code has a chance to install your event handlers.

How do I register a listener for a onMessage event on a Port with chrome.dart

I have a chrome extension and I want to use the chrome.runtime.connect functionality to create a connection between my pageAction and the background page. I got stuck while trying to register a listener for the incoming messages.
My question is that I am looking for a working example of exchanging messages over a connection in chrome.dart.
I started by listening for newly created connections. chrome.runtime.OnConnect is an event stream, so I can just listen.
chrome.runtime.onConnect.listen((chrome.Port p) {
...
}
Now, the Port instances have an accessor p.onMessage, which is a chrome.ChromeEvent object. ChromeEvent instances provide a method with the following signature Future addListener().
I tried messing around with the p.onMessage and also the value returned from the future returned after calling p.onMessage.addListener, but I got nowhere. I have no idea what to put instead of the three dots.
The only thing that works for me is looking into the JavaScript API documentation and emulateing with dart:js what they do there.
p.onMessage.jsProxy.callMethod('addListener', [listener]);
while of course having previously defined the listener function as
listener(message, s) {
print('message: $message');
print('message.runtimeType: ${message.runtimeType}');
print('s: $s');
print('s.runtimeType: ${s.runtimeType}');
throw('halt');
}
I believe that the automatic API generation for Dart somehow messed up the API here.
There is actually a bug for this, https://github.com/dart-gde/chrome.dart/issues/135

Categories

Resources