【问题标题】:Socket.IO: TypeError: Object has no method packetSocket.IO:TypeError:对象没有方法包
【发布时间】:2014-10-17 14:42:10
【问题描述】:

我遇到了使用 Socket.IO 发出全局事件的问题。 顺便说一句,这是一个服务器端错误,而不是 #489

发生错误的情况

nsp = io.of('/namespace');
nsp.emit('hello', 'there');

io.emit('hello', 'there');

io.sockets.emit('hello', 'there');

var needed_namespace = '/my_namespace';
io.nsps[needed_namespace].emit('hello', 'there');

在每种情况下,我都有以下错误:

TypeError: Object function (key) {
    if (!this[key]) {
      return this[key] = 1;
    } else {
        return this[key] += 1;
    }
} has no method 'packet'
at /Users/nr/Git/lt-connection/node_modules/socket.io/node_modules/socket.io-adapter/index.js:125:28
at Encoder.encode (/Users/nr/Git/lt-connection/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser
at Adapter.broadcast (/Users/nr/Git/lt-connection/node_modules/socket.io/node_modules/socket.io-adapter/index.js:107:16)
at Namespace.emit (/Users/nr/Git/lt-connection/node_modules/socket.io/lib/namespace.js:218:18)
at SocketTransport.global.SocketTransport.SocketTransport.deliver (/Users/nr/Git/lt-connection/lib/prototype/socket.coffee:40:26)
at SocketTransport.global.SocketTransport.SocketTransport.emit (/Users/nr/Git/lt-connection/lib/prototype/socket.coffee:11:6)
at SocketTransport.global.SocketTransport.SocketTransport.send_from_http (/Users/nr/Git/lt-connection/lib/prototype/socket.
at Object.exports.routes.handlers.post (/Users/nr/Git/lt-connection/lib/http_server/routes/socket_router.coffee:9:11)
at apply (/Users/nr/Git/lt-connection/node_modules/director/lib/director/router.js:444:19)
at _every (/Users/nr/Git/lt-connection/node_modules/director/lib/director/router.js:28:9)
at [object Object].Router.invoke (/Users/nr/Git/lt-connection/node_modules/director/lib/director/router.js:450:5)
at parseAndInvoke (/Users/nr/Git/lt-connection/node_modules/director/lib/director/http/index.js:175:10)
at [object Object].Router.dispatch (/Users/nr/Git/lt-connection/node_modules/director/lib/director/http/index.js:198:7)
at /Users/nr/Git/lt-connection/lib/http_server/index.coffee:31:13
at IncomingForm.<anonymous> (/Users/nr/Git/lt-connection/node_modules/formidable/lib/incoming_form.js:104:9)
at IncomingForm.emit (events.js:92:17)
at IncomingForm._maybeEnd (/Users/nr/Git/lt-connection/node_modules/formidable/lib/incoming_form.js:551:8)
at QuerystringParser.parser.onEnd (/Users/nr/Git/lt-connection/node_modules/formidable/lib/incoming_form.js:446:10)
at QuerystringParser.end (/Users/nr/Git/lt-connection/node_modules/formidable/lib/querystring_parser.js:25:8)
at IncomingMessage.<anonymous> (/Users/nr/Git/lt-connection/node_modules/formidable/lib/incoming_form.js:129:30)
at IncomingMessage.emit (events.js:92:17)
at _stream_readable.js:938:16
at process._tickCallback (node.js:419:13)

发生错误的实际代码(它是从 CoffeeScript 编译的,抱歉可读性):

deliver: function(message, channel, namespace, socket) {
    var err;
    socket = this.get_namespace(namespace, socket);
    message = this.prepage_message(message);
    try {
        if (channel != null) {
        //error occur here (line 125:28 from error stack)
        return socket.emit(channel, message);
    }
        //also error will be here when 'channel' not passed to '.deliver()'
        return socket.emit(message);
    } catch (_error) {
        err = _error;
        return console.warn('Something may be wrong: ' + err.stack);
    }
},

get_namespace: function(ns, socket) {
    var namespace, _ref;
    if (socket != null) {
        return socket;
    }
    namespace = null;
    if ((namespace = this.namespaces[ns]) != null) {
        return namespace;
    } else if ((namespace = (_ref = this.io.nsps) != null ? _ref[namespace] : void 0) != null) {
        return this.namespaces[ns] = namespace;
    } else {
        return this.create_namespace(ns);
    }
},

create_namespace: function(ns) {
    var socket;
    if (ns == null) {
        ns = '/';
    }
    socket = this.io;
    if (ns !== '/') {
        socket = socket.of(ns);
    }
    this.namespaces[ns] = socket;
    return socket;
}

有什么解决办法吗?还是我做错了? 顺便说一句,其中两个案例列在official docs

GitHub上也有问题:#1747

UPD:

另一个堆栈跟踪:

  socket.io-parser encoding packet {"type":2,"data":["hello","world"],"nsp":"/"} +0ms
  socket.io-parser encoded {"type":2,"data":["hello","world"],"nsp":"/"} as 2["hello","world"] +0ms

/Users/nr/Git/lt-connection/node_modules/socket.io/node_modules/socket.io-adapter/index.js:125
        if (socket) socket.packet(encodedPackets, true, flags.volatile);
                           ^
TypeError: Object function (key) {
    if (!this[key]) {
      return this[key] = 1;
    } else {
      return this[key] += 1;
    }
  } has no method 'packet'
  at /Users/nr/Git/lt-connection/node_modules/socket.io/node_modules/socket.io-adapter/index.js:125:28
  at Encoder.encode (/Users/nr/Git/lt-connection/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/index.js:110:5)
  at Adapter.broadcast (/Users/nr/Git/lt-connection/node_modules/socket.io/node_modules/socket.io-adapter/index.js:107:16)
  at Namespace.emit (/Users/nr/Git/lt-connection/node_modules/socket.io/lib/namespace.js:218:18)
  at Server.(anonymous function) [as emit] (/Users/nr/Git/lt-connection/node_modules/socket.io/lib/index.js:338:16)
  at SocketTransport.global.SocketTransport.SocketTransport.deliver (/Users/nr/Git/lt-connection/lib/prototype/socket.coffee:40:15)
  at SocketTransport.global.SocketTransport.SocketTransport.emit (/Users/nr/Git/lt-connection/lib/prototype/socket.coffee:11:6)

【问题讨论】:

    标签: javascript node.js socket.io socket.io-1.0


    【解决方案1】:

    你能试着用 setInterval 来看看这个问题吗?可能是因为上下文不同。

    https://github.com/Automattic/socket.io/issues/489

    您正在使用一个对象(类?)来存储您的方法,因此它可能处于错误的上下文中。

    【讨论】:

    • 是的,这就是 Socket.IO 的类包装器。但正如您在我的代码中看到的那样,没有 setTimeout。我的类上下文如何影响套接字的上下文?我应该更新问题。服务器端出错。
    • 顺便说一句,我使用带有本机上下文的 socket.io 实例,没有任何修改。我的意思是在我的代码中没有像 socket.emit.bind(ctx) 这样的东西。也没有像setTimeout(socket.emit, 1000)这样的结构。
    • 你不是在向不存在的命名空间发出信号吗?我的意思是:var required_namespace = '/my_namespace';
    • 不,现在我只是尝试将消息发送到默认命名空间,如 io.emit('hello', 'world')io.sockets.emit('hello', 'world'),就像在 socket.io 上的文档中一样。检查表明发射到默认 nsp 或不存在之间没有区别。但我的代码处理不存在的 nsps,如果需要,它会创建一个。无论如何,命名空间没有问题。问题出在socket.io-adapter 某处,但现在我不知道具体在哪里。
    • 你试过重新安装socket.io吗?是否给您任何错误?
    【解决方案2】:

    谢谢大家。问题已解决,是由我的应用程序和修改后的 Object 原型引起的:

    global.Object.prototype.increment = function(key) {
        if(!this[key]){
            this[key] = 1;
        }else{
            this[key] += 1;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-19
      • 1970-01-01
      • 2012-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-11
      • 2014-05-17
      相关资源
      最近更新 更多