Socket.io和Express收到错误“没有方法套接字”

时间:2012-02-29 18:43:20

标签: node.js express socket.io

这是我在尝试测试基本的Socket.io和Express设置时遇到的错误(根据socket.io网站上的示例):

/Users/scottcorgan/Projects/sevenly/campaigns/node_modules/socket.io/lib/manager.js:659

        var socket = this.namespaces[i].socket(data.id, true);



 ^

TypeError: Object function extend(another) {
  var properties = Object.keys(another);
  var object = this;
  properties.forEach(function (property) {
    object[property] = another[property];
  });
  return object;
} has no method 'socket'
    at Manager.handleClient (/Users/scottcorgan/Projects/sevenly/campaigns/node_modules/socket.io/lib/manager.js:659:41)
    at Manager.handleUpgrade (/Users/scottcorgan/Projects/sevenly/campaigns/node_modules/socket.io/lib/manager.js:588:8)
    at HTTPServer.<anonymous> (/Users/scottcorgan/Projects/sevenly/campaigns/node_modules/socket.io/lib/manager.js:119:10)
    at HTTPServer.emit (events.js:88:20)
    at Socket.<anonymous> (http.js:1390:14)
    at TCP.onread (net.js:334:27)

感谢我能得到的任何帮助,请:)

2 个答案:

答案 0 :(得分:1)

此问题源于您或您使用的库正在向 Object.prototype 添加功能。

因此这段代码:

Object.prototype.foo = function() {};
Object.prototype.bar = function() {};

var myObj = { x: 1 };

for (var i in myObj) {
   console.log(i)
}

将打印: x,foo,bar (不一定按此顺序)而不只是 x 如你所料。

在你的情况下,这发生在manager.js:

// initialize the socket for all namespaces
for (var i in this.namespaces) {
    var socket = this.namespaces[i].socket(data.id, true);

    // echo back connect packet and fire connection event
    if (i === '') {
        this.namespaces[i].handlePacket(data.id, { type: 'connect' });
    }
}

此代码不会遇到声明的: extend 键,正如您可以从错误的堆栈跟踪中看到的那样:

TypeError: Object function extend(another) {
  var properties = Object.keys(another);
  var object = this;
  properties.forEach(function (property) {
    object[property] = another[property];
  });
  return object;
} has no method 'socket'

该程序实际上是尝试在 扩展 功能上调用 socket()

有关向 Object.prototype 添加功能的信息,请参阅Bob's rant here

至于解决方案,您可以在manager.js中添加条件语句,如下所示:

// initialize the socket for all namespaces
for (var i in this.namespaces) {
    if ('extend' == i) continue;  // ADDED
    var socket = this.namespaces[i].socket(data.id, true);

    // echo back connect packet and fire connection event
    if (i === '') {
        this.namespaces[i].handlePacket(data.id, { type: 'connect' });
    }
}

或者您可以删除 Object.prototype.extend = function(...){} 声明,这是我个人的偏好。

答案 1 :(得分:0)

您的this.namespaces[i].socket(data.id, true);不存在。执行类似console.log(typeof this.namespaces[i].socket(data.id, true));的操作您可能会获得undefined

我打赌你的命名空间数组的一个元素缺失了。