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