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

Node.js - socket.io - reference to io.sockets suddenly undefined

本文关键字:引用 突然 未定义 sockets io js-socket io- Node      更新时间:2023-09-26

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

当我引用this.io.sockets来建立一个"连接"处理程序函数时,它工作得很好。但如果我后来引用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)将不同。

你应该做的是,至少有三种方法,但我建议使用一种

将作用域保存到一个变量中,并由类似的侦听器关闭

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

问题是,每当您将函数声明为套接字事件的回调时,该函数都会有自己的作用域/上下文。这意味着您将丢失this的值。默认情况下,在这种情况下,this实际上指的是在.中运行回调函数的任何上下文套接字

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

为了避免自己陷入回调地狱,您可以单独声明函数,如下所示:

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