Socket.io + node : TypeError: Object #<Namespace> has no method

Socket.io + node : TypeError: Object #<Namespace> has no method

我有一个简单的 JavaScript class :

function MySIOClass(io)
{
    this.io = io
    this.ns = this.io.of('/notif')
    this.init()
}

MySIOClass.prototype.init = function (){
  this.ns.on('connection', this.newClient)
}

MySIOClass.prototype.newClient = function (socket)
{
  socket.on('msg', function (data){ this.handle_msg(data)})

 }

MySIOClass.prototype.handle_msg = function (data)
{
    // handle my message
}

我卡在函数 newClient 上,每次 socket.io 客户端发送一个事件 'msg' , 控制台触发器

TypeError: Object #<Socket> has no method 'handle_msg'

我试图在函数 newClient 中保留对运算符 this 的引用:

MySIOClass.prototype.newClient = function (socket)
{
  var c = this;
  socket.on('msg', function (data){ c.handle_msg(data)})

 }

但也不走运,我收到以下关于命名空间的错误:

TypeError: Object #<Namespace> has no method 'handle_msg'

我的 class 是通过模块导出的,一切正常,除非我尝试使用 [=46] 的 on 方法添加侦听器=]里面一个class。我在实例化 class.

时正确使用了“new”运算符

你能帮我弄清楚发生了什么吗?我尝试了几件事,但没有一个奏效。

感谢您的宝贵时间。

当您将 this.newClient 传递给 .on('connection', ...) 时,您传递的只是函数本身,而丢失了 (this) 上下文。您需要创建一个可以访问正确上下文以正确调用 newClient() 的包装函数,或者创建 newClient.

的绑定版本

第一个选项:

MySIOClass.prototype.init = function (){
  var self = this;
  this.ns.on('connection', function(socket) {
    self.newClient(socket);
  });
}

第二个选项:

MySIOClass.prototype.init = function (){
  this.ns.on('connection', this.newClient.bind(this));
}

关于 newClient() 本身的错误,你是正确的,因为你必须使用 "self"/"that" 变量,你可以使用它来访问正确的上下文来调用 handle_msg().