Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js / Server.js socket implementation problems

Having a hard time implementing a node.js/server.js setup

I'm a bit stuck right now, and hoping someone can shed some light. I'm relatively new to sockets in general, but have been programming in javascript on and off for several years, although only about as deep as is necessary to accomplish the task at hand. As a result, my understanding of some of the concepts surrounding the javascript stack heap, and sockets in general are somewhat limited. Ok Here's the situation:

I've created an application intended to simply increment a counter, on several machines. Several users can click the "next" button and it will update instantly on all machines. When you first connect, it retrieves the current number, and spits it out locally.

I've created the server here:

var io = require("socket.io"); var sockets = io.listen(8000); var currentlyServing=0; sockets.on("connection", function (socket) {      console.log("client connected");     socket.emit("receive", currentlyServing);     socket.on("update", function(serving)     {         currentlyServing=serving;         if(currentlyServing>100)             currentlyServing=0;         if(currentlyServing<0)             currentlyServing=99;         socket.broadcast.emit("receive", currentlyServing);         console.log("update received: "+currentlyServing);     }); }); console.log("Server Started"); 

Here is the relevant (I hope) excerpt from the client side:

var socket = io.connect("http://www.sampledomain.com:8000");  //function to update the page when a new update is received socket.on("receive", function(receivedServing) {     document.getElementById('msgs').value=""+String("00" + receivedServing).slice(-2);     document.getElementById('nowServing').value=receivedServing; });  //this is called in an onClick event in the HTML source //sends the new number to all other stations except this one (handled by server side) function nextServing()  {     var sendServing = parseInt(document.getElementById('nowServing').value)+1;     socket.emit("update", sendServing);     document.getElementById('nowServing').value=sendServing;     document.getElementById('msgs').value=""+String("00" + sendServing).slice(-2); } 

Ok so here's my problem. This runs absolutely fine in every system I've put it in, smoothly and beautifully - except for IE8. If left alone for more than 2-3 minutes (with no activity at all), I eventually receive a "stack overflow" error. The line number it appears on fluctuates (haven't determined the factors involved yet), but it always happens at that interval. On some workstations it takes longer, which I'm beginning to think has a direct correlation to the amount of phsyical RAM the machine has, or at least how much is being allocated to the web browser.

I found an online function to determine "max stack size", which I realize is not an exact science, however I did consistently get a number in the area of 3000. On my IE11 machine with considerable more resources, I found it to be in the area of 20,000. This may not be relevant, but I figured the more info the better :)

To avoid this problem for now so that the end users don't see this error message, I've take the entire client script, and put it into an iFrame which reloads itself every 60 seconds,essentially resetting the stack, which feels so dirty sitting so close to a web socket, but has bought me the time to post here. I've googled until I can't google any more, but when you search "node.js" or "socket.io" along with "stack overflow" on google, you just get a lot of posts about the two topics that are hosted on the stackoverflow dot com website. ARG lol

Anyone?

EDIT ON NOVEMBER 18TH 2014 AS PER COMMENTS BELOW:

the error message is most often claiming stack overflow at line 1056. IE Developer tools points towards the file socket.io.js. Line 1056 is:

return fn.apply(obj, args.concat(slice.call(arguments))); 

which is insdie this section of the file:

var slice = [].slice;  /**  * Bind `obj` to `fn`.  *  * @param {Object} obj  * @param {Function|String} fn or string  * @return {Function}  * @api public  */   module.exports = function(obj, fn){   if ('string' == typeof fn) fn = obj[fn];   if ('function' != typeof fn) throw new Error('bind() requires a function');   var args = slice.call(arguments, 2);   return function(){     return fn.apply(obj, args.concat(slice.call(arguments)));   } }; 
like image 738
Dale Avatar asked Nov 11 '14 07:11

Dale


People also ask

How do you implement a Socket in node JS?

// make a connection with the user from server side io. on('connection', (socket)=>{ console. log('New user connected'); }); Similarly, from the client-side, we need to add a script file and then make a connection to a server through which users send data to a server.

Why is Socket.IO not working?

First and foremost, please note that disconnections are common and expected, even on a stable Internet connection: anything between the user and the Socket.IO server may encounter a temporary failure or be restarted. the server itself may be killed as part of an autoscaling policy.

Is Node JS good for WebSockets?

Node. js can maintain many hundreds of WebSockets connections simultaneously. WebSockets on the server can become complicated as the connection upgrade from HTTP to WebSockets requires handling. This is why developers commonly use a library to manage this for them.

How to implement the WebSocket client on Node JS?

To implement the WebSocket client on Node.js, you can use one of the many package libraries available. One of the simplest is ' websocket-node ,' a pure JavaScript implementation of the WebSocket protocol for Node.

What is socket Io in Java?

Socket.IO is a library that enables real-time, bidirectional and event-based communication between the browser and the server. We can connect client and server responding to each other using socket.io. BUT Socket.IO is NOT a WebSocket implementation.

What is node Node JS?

Node.js is a JavaScript runtime environment built on Chrome’s V8 JavaScript engine, it implements the reactor pattern, a non-blocking, event-driven I/O paradigm. You definitely don’t want to use Node.js for CPU-intensive operations, using it for heavy computation will annul nearly all of its advantages.

Does Node JS server use too much CPU time?

But when your product and user base grows, you will face a problem, your node.js server will use too much CPU time. Check this article on how to implement AWS S3 + AWS Cloudfront for doing this task.


2 Answers

From what I've read it seems that the problem on IE8 might be related to flash. It IE8 uses flashsocket as the default configuration. I suggest to try the following on the client side:

 if(navigator.appName.indexOf("Internet Explorer")!=-1 && navigator.appVersion.indexOf("MSIE 8")==-1 ){             socket = io.connect("http://www.sampledomain.com:8000", {            transports: ['xhr-polling']       });  }  else  {        socket = io.connect("http://www.sampledomain.com:8000" );  } 

This should make IE8 use long polling while all other machines use the best method they can.

On a side note: You might also want to consider incrementing the "serving" variable on the server.

like image 190
bert Avatar answered Oct 12 '22 22:10

bert


Find existing issue Causes a "Stack Overflow" in IE8 when using xhr-polling #385.

This was fixed by disabling Flash.

Also find Safari over windows client use xhr-polling instead of websocket - performance are severely harm #1147. While this is Safari it may apply to IE8 because it is using similar mechanism.

I did a small test using your socket.io but in IE 10 and emulated IE8 so that I could debug well. Started capturing Network in the tab and noticed the requests logging every few seconds.Left alone for few minutes and I see a lot of requests logged in. You will not see this in Chrome because it has true WebSockets. While IE8 does not support WebSockets socket.io emulate that using plain HTTP GET/POST using some mechanism. So my theory is that even if socket.io works with IE8 it does not reliably emulate web sockets

My advice is to rule out IE 8 for long running client application. IE8 is no longer supported by Microsoft.

like image 33
bhantol Avatar answered Oct 12 '22 22:10

bhantol