Node.js – socket.io – 对io.sockets的引用突然未定义

我有一个node.js服务器运行一个简单的socket.io服务

当我引用this.io.sockets为了build立一个“连接”处理函数,它工作正常。 但是,如果我稍后引用this.io.sockets ,我得到一个错误

 TypeError: Cannot read property 'sockets' of undefined 

我很新的node.js所以我不知道我在做什么错在这里。

码:

 var app = require('http').createServer(); var port = 8080; app.listen(port); function Serv() { this.io = require('socket.io')(app) this.addHandlers() } Serv.prototype.addHandlers = function () { this.io.sockets.on("connection", function (socket) { console.log('new connection'); socket.on('disconnect', function () { console.log('disconnection'); if (this.io.sockets.adapter.rooms[phn] != null) { //Causes undefined error.. //do something } }); socket.on(SOCKETEVENTMESSAGE, function (data) { if (this.io.sockets.adapter.rooms[phn] != null) { //Causes undefined error.. //do something } }); }); }; // Start the server var serv = new Serv(); console.log('socket.io listening on ' + port); 

正如你所看到的,这个问题是显而易见的

 this.io.sockets.on("connection", function (socket) { 

当连接发生时,监听器将被调用,因此范围( this )将会不同。

你应该做的是,至less有三种方法,但我会build议一种

将范围保存到一个variables,并通过监听器closures

 Serv.prototype.addHandlers = function () { var _this = this; this.io.sockets.on("connection", function (socket) { console.log('new connection'); socket.on('disconnect', function () { console.log('disconnection'); if (_this.io.sockets.adapter.rooms[phn] != null) { //do something } }); 

问题是,只要你声明一个函数作为套接字事件的callback函数,就给它自己的作用域/上下文。 这意味着你失去了这个价值。 默认情况下,在这种情况下, this实际上是指任何上下文套接字已经在其中运行callback函数。

JavaScript附带内置的方式来确保您所需的上下文被使用: bind

 Serv.prototype.addHandlers = function () { this.io.sockets.on("connection", function (socket) { console.log('new connection'); socket.on('disconnect', function () { console.log('disconnection'); if (this.io.sockets.adapter.rooms[phn] != null) { 'this' has correct value //do something } }.bind(this)); socket.on(SOCKETEVENTMESSAGE, function (data) { if (this.io.sockets.adapter.rooms[phn] != null) { 'this' has correct value //do something } }.bind(this)); }.bind(this)); }; 

为了避免陷入callback地狱 ,你可以单独声明函数,如下所示:

 Serv.prototype.addHandlers = function () { var onDisconnect = function () { console.log('disconnection'); if (this.io.sockets.adapter.rooms[phn] != null) { //do something } }.bind(this); var handleEvent = function (data) { if (this.io.sockets.adapter.rooms[phn] != null) { //do something } }.bind(this); function onConnect (socket) { console.log('new connection'); socket.on('disconnect', onDisconnect); socket.on(SOCKETEVENTMESSAGE, onHandleEvent); }; // 'this' isn't required, so no binding necessary this.io.sockets.on("connection", onConnect); };