admin管理员组

文章数量:1314086

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 acplish 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(":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 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)));
  }
};

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 acplish 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.: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 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)));
  }
};
Share Improve this question edited Nov 19, 2014 at 4:13 Dale asked Nov 11, 2014 at 7:12 DaleDale 3192 silver badges8 bronze badges 11
  • Which version of socket.io are you using? The latest? I found some issues on the github issues page that may be relevant here and here hope that might help. – Vadim Commented Nov 18, 2014 at 20:33
  • It looks like I'm using 1.1.0 - I got that from the History.md file. Thinking I can't remove flash from all of my clients machines (re: first link), and the code mentioned in the second link seems to have been changed in the subsequent versions. Got my hopes up there lol – Dale Commented Nov 18, 2014 at 22:58
  • Have you tried putting a breakpoint in 'nextServing()'? I would check this first to ensure there is no infinite loop. Does the error always throw within your code or is it within the socket.io code itself? – allen-smithee Commented Nov 19, 2014 at 0:48
  • The IE 8 stack overflow error is notoriously hard to debug. I don't see a problem in posted code, so I would advise disable the code part by part until you can narrow it down to a few lines. – Sheepy Commented Nov 19, 2014 at 4:05
  • 1 I do not know if socket.io uses flash, but you can set to use long polling on browser that does not support websockets, this should avoid the use of flash. – albanx Commented Nov 25, 2014 at 17:14
 |  Show 6 more ments

3 Answers 3

Reset to default 1

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.:8000", {
           transports: ['xhr-polling']
      });
 }
 else
 {
       socket = io.connect("http://www.sampledomain.: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.

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.

maybe try to replace

""+String("00" + receivedServing).slice(-2)

with

('00' + receivedServing).slice(-2)

本文标签: javascriptNodejsServerjs socket implementation problemsStack Overflow