I have a node.js server running a simple socket.io service
When I reference this.io.sockets
in order to establish a "connection" handler function, it works fine. But if I later reference this.io.sockets
, I get an an error
TypeError: Cannot read property 'sockets' of undefined
I'm pretty new to node.js so am not sure what I am doing wrong here.
Code:
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);
As you can see, the issue is obvious
this.io.sockets.on("connection", function (socket) {
Listener will be called whenever a connection happens, therefore the scope( this
) will be different.
What you should be doing is, there are at least three ways, but I'd suggest one
Save the scope to a variable and close in by the listener like
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
}
});
The problem is that whenever you declare a function as a callback to your socket events, the function is given its own scope/context. This means that you lose the value of this
. By default, in that situation, this
actually refers to whatever context socket has run the callback function in.
JavaScript comes with a built in way to ensure that the context you want is used: 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));
};
To save yourself from getting too far into callback hell , you could declare the functions individually, something like 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);
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.