【问题标题】:Calling functions on socket message (socket.io/node.js)在套接字消息上调用函数 (socket.io/node.js)
【发布时间】:2012-02-03 22:04:42
【问题描述】:

当我启动一个新的 GameServer 实例时,它会按如下方式设置套接字和侦听器。

var GameServer = function() {
    this.player = new Player();
    var that = this;

    // Setup sockets and listeners
    var socket = io.listen(8000);
    socket.sockets.on('connection', function(client) {
        client.on('message', that.onSocketMessage);
        client.on('disconnect', that.onSocketDisconnect);
    });
}

然后我有两个原型 GameServer.prototype.onSocketMessage 和 onSocketDisconnect。

我当前的代码有两个问题:

  1. 使用that = this 和闭包?功能。看起来很丑。

  2. 当 onSocketMessage 被调用时,想法是它计算出消息是什么,然后调用 GameServer 中的另一个函数。只有这是不可能的,因为现在它属于 socket.io 系统。见下文:

...

function onSocketMessage() {
    this.player.move();
}

this.player 不再可用。不再是 GameServer 的一部分。

是否应该在 GameServer 函数和原型之外处理我的套接字设置和消息传递?

或者我还能如何解决这个问题?

干杯

编辑

好的,我已经尝试过了,它可以工作,但我认为它看起来很丑:

var socket = io.listen(8000);
socket.sockets.on('connection', function(client) {
    client.on('message', function (data) {
        that.onSocketMessage(this, that, data);
    });
    client.on('disconnect', function() {
        that.onSocketDisconnect(this, that);
    });
});

可以改进吗?

【问题讨论】:

    标签: javascript node.js closures socket.io


    【解决方案1】:

    有两件事可能会有所帮助。第一件事:

    您可以使用the bind method 修改函数对this 的看法。

    socket.sockets.on('connection', function(client) {
        client.on('message', this.onSocketMessage);
        client.on('disconnect', this.onSocketDisconnect);
    }.bind(this));
    

    注意函数末尾对bind(this)的调用;这指示 JavaScript 为您创建一个闭包,使 this 在函数外部,this 在函数内部。 (如果你想在函数中创建this,比如MySomething,你可以很容易地调用bind(MySomething),尽管bind(this)是最常用的)。

    第二件事:

    您可以将数据存储在 Socket.IO 套接字中。因此,例如,如果一个套接字始终与一个播放器相关联,您可以这样做

    socket.set('player', player, function() {
      // callback is called when variable is successfully stored
      console.log('player has been stored');
    });
    
    // and later
    
    socket.get('player', function(err, player) {
      // callback is called either with an error set or the value you requested
      player.move();
    });
    

    getset 方法接受回调,因为 Socket.IO 数据存储可以设置为内存存储以外的其他内容;例如,Redis。

    【讨论】:

    • 绑定选项完美运行。有趣的是,我已经尝试过 bind 但我没有正确地实现它并且它没有工作。现在我明白为什么了!但问题:'client.on('message', this.onSocketMessage.bind(this));'当收到该消息时,通常在 onSocketMessage 中,您将拥有 this.id 可用(这将是客户端/套接字 id)和(数据)传递到您的函数中。数据仍然传递,但我不再有任何访问 this.id 的权限。我怎样才能把它也传进去?
    • 你不能;这就是为什么bind 只对您的第一个问题有用。对于您的第二个问题,我会以其他方式将player 引入该方法。
    猜你喜欢
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-21
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    • 2014-12-24
    相关资源
    最近更新 更多