【问题标题】:Node.js / Server.js socket implementation problemsNode.js / Server.js 套接字实现问题
【发布时间】:2015-01-07 16:24:18
【问题描述】:

很难实现 node.js/server.js 设置

我现在有点卡住了,希望有人能解释一下。一般来说,我对套接字相对较新,但多年来一直在使用 javascript 进行编程,尽管只有完成手头任务所需的深度。因此,我对围绕 javascript 堆栈堆和一般套接字的一些概念的理解有些有限。 好的,情况如下:

我创建了一个应用程序,用于在多台机器上简单地增加一个计数器。几个用户可以单击“下一步”按钮,它会立即在所有机器上更新。 当您第一次连接时,它会检索当前号码,并在本地将其吐出。

我在这里创建了服务器:

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");

这是来自客户端的相关(我希望)摘录:

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);
}

好的,这是我的问题。这在我放入的每个系统中都运行得非常好,流畅而精美 - 除了 IE8。如果单独放置超过 2-3 分钟(根本没有活动),我最终会收到“堆栈溢出”错误。它出现的行号会波动(尚未确定所涉及的因素),但它总是在那个间隔发生。在某些工作站上,它需要更长的时间,我开始认为这与机器拥有的物理 RAM 的数量直接相关,或者至少与分配给 Web 浏览器的数量有关。

我找到了一个在线函数来确定“最大堆栈大小”,我意识到这不是一门精确的科学,但是我确实得到了一个 3000 范围内的数字。在我的 IE11 机器上,我找到了更多资源在20,000的范围内。这可能不相关,但我认为信息越多越好:)

为了暂时避免这个问题,以便最终用户看不到这个错误消息,我已经将整个客户端脚本放入一个 iFrame 中,它每 60 秒重新加载一次,基本上是重置堆栈,这坐在离网络插座很近的地方感觉很脏,但让我有时间在这里发帖。我已经用谷歌搜索了,直到我不能再用谷歌搜索了,但是当你在谷歌上搜索“node.js”或“socket.io”以及“堆栈溢出”时,你只会得到很多关于这两个主题的帖子托管在 stackoverflow dot com 网站上。 ARG 哈哈

有人吗?

根据以下评论于 2014 年 11 月 18 日编辑:

错误消息通常在第 1056 行声称堆栈溢出。IE 开发工具指向文件 socket.io.js。第 1056 行是:

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

这是文件的这一部分:

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)));
  }
};

【问题讨论】:

  • 您使用的是哪个版本的 socket.io?最新的?我在 github 问题页面上发现了一些可能与 herehere 相关的问题,希望对您有所帮助。
  • 看起来我使用的是 1.1.0 - 我是从 History.md 文件中得到的。认为我无法从我的所有客户端计算机中删除闪存(re:第一个链接),并且第二个链接中提到的代码似乎在后续版本中已更改。让我的希望在那里大声笑
  • 你试过在'nextServing()'中设置断点吗?我会先检查一下以确保没有无限循环。错误总是在您的代码中抛出还是在 socket.io 代码本身中?
  • IE 8 堆栈溢出错误是出了名的难以调试。我在发布的代码中没有看到问题,因此我建议您逐步禁用代码,直到您可以将其缩小到几行。
  • 不知道socket.io有没有使用flash,但是你可以在不支持websockets的浏览器上设置使用长轮询,这样应该避免使用flash。

标签: javascript node.js sockets stack stack-overflow


【解决方案1】:

可以尝试替换

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

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

【讨论】:

  • 不,String() 不应该new 调用! new String("abc") 结果为 {"0": "a", "1": " b", "2": "c"}
【解决方案2】:

查找现有问题Causes a "Stack Overflow" in IE8 when using xhr-polling #385

已通过禁用 Flash 解决此问题。

也可以找到Safari over windows client use xhr-polling instead of websocket - performance are severely harm #1147。虽然这是 Safari,但它可能适用于 IE8,因为它使用了类似的机制。

我使用你的 socket.io 做了一个小测试,但在 IE 10 中并模拟了 IE8 这样我就可以很好地调试了。开始在选项卡中捕获网络并 注意到每隔几秒就会记录一次请求。只留下几个 分钟,我看到很多请求登录。你不会看到这个 在 Chrome 中,因为它具有真正的 WebSockets。虽然 IE8 不支持 WebSockets socket.io 模拟使用普通 HTTP GET/POST 使用一些 机制。所以我的理论是,即使 socket.io 与 IE8 一起使用它 不能可靠地模拟网络套接字

我的建议是排除 IE 8 用于长时间运行的客户端应用程序。 IE8 is no longer supported by Microsoft.

【讨论】:

  • 我也确实将其作为一个选项阅读 - 但不幸的是,从 IE8 升级不是一个选项,因为我的客户正在使用另一家公司的一些基于 Web 的软件,这些软件需要 IE8 才能运行。不要让我开始谈论那个话题,大声笑。底线是我们必须使我们所做的一切向后兼容,可以追溯到 IE8。也不能禁用闪存,因为这些其他应用程序需要它。今天下午将尝试这些其他解决方案 - 我的赏金时间不多了
【解决方案3】:

从我读到的内容看来,IE8 上的问题可能与闪存有关。它 IE8 使用 flashsocket 作为默认配置。我建议在客户端尝试以下操作:

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

这应该使 IE8 使用长轮询,而所有其他机器都使用它们可以使用的最佳方法。

附带说明:您可能还需要考虑增加服务器上的“服务”变量。

【讨论】:

  • 您是说 !=-1 代表 MSIE 8 吗?
  • 刚刚发现这是一个 IE 8 浏览器,IE8 浏览器模式,但 IE7 标准文档模式,你认为这会改变什么吗?
  • 试过了 ("MSIE 8")==-1, ("MSIE 8")!=-1, and ("MSIE 7")!=-1 不幸的是没有运气仍然让堆栈溢出错误:(
猜你喜欢
  • 2021-03-22
  • 2011-10-31
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
  • 1970-01-01
  • 2015-07-17
  • 2017-04-15
相关资源
最近更新 更多