你能在signalr客户端事件中指定上下文吗?

时间:2013-06-02 18:59:22

标签: c# backbone.js requirejs signalr

我正在尝试将信号器用于棋盘游戏应用程序,这样当玩家在一个客户端上移动一个棋子时,所有客户端都可以更新。我遇到的问题是没有一个明确的方法来抽象应用程序的信号器部分,以便它的消费者不需要担心启动连接等事情。我决定跳过生成的代理而不是调用事情直接。唯一剩下的障碍是,当客户端从服务器接收到请求时,事件回调中的此上下文是集线器,而不是回调的所有者。我想知道是否有办法传递上下文。

代码:

Signalr服务(就像管理连接和最终事件的基类一样):

define('service.signalr', ['jquery'], function ($) {
var connection = $.hubConnection();

var start = function () {
    connection.start();
};

return {connection: connection, start: start}
});

具有特定功能的服务 - 在这种情况下处理件移动:

define('service.game', ['jquery', 'service.signalr'], function ($, signalr) {

var gameHubProxy = signalr.connection.createHubProxy('gameHub');

var addHandler = function (name, callback) {
    gameHubProxy.on(name, callback);
}

var moveFigure = function (figureId, targetSpaceId) {
    var deferred = $.Deferred();
    gameHubProxy.invoke('moveFigure', figureId, targetSpaceId).done(function () { deferred.resolve(); });
    return deferred.promise();
};

return { moveFigure: moveFigure, addHandler: addHandler }
});

在服务上调用服务器方法(事件触发器用于执行操作的客户端,因此它不会处理两次):

define('model.space', ['backbone', 'service.game'], function (Backbone, gameService) {
var Space = Backbone.Model.extend({
    defaults: { id: 0, figure: null },
    moveFigure: function (figureId) {
        var self = this;
        var spaceId = self.get('id');
        gameService.moveFigure(figureId, spaceId).done(function () {
            self.trigger('figureMoved', figureId, spaceId, false);
        });
    }
});

return Space;
});

试着听服务器的回复:

define('view.board', ['jquery', 'underscore', 'backbone', 'helpers', 'bootstrapData', 'service.game', 'aggregate.space'], function ($, _, Backbone, helpers, bootstrapData, gameService, Space) {
var Board = Backbone.View.extend({
    initialize: function () {
        this.spaces = new Space.Collection(bootstrapData.spaces);

        this.listenTo(this.spaces, 'figureMoved', this.updateFigurePosition);
        gameService.addHandler('figureMoved', this.updateFigurePosition);
    },
    updateFigurePosition: function (figureId, spaceId, drawFigure) {
        var figure = null;
        var oldSpace = this.spaces.find(function (space) {
            figure = space.get('figure');
            return figure && figure.id == figureId;
        });

        //code continues, but has already failed on this.spaces
    },
});

return Board;
});

1 个答案:

答案 0 :(得分:0)

在一些睡眠之后,明显的答案是将回调连接到模块中的一个函数,我想要的上下文只是我要调用的实际方法的一个直通,这样就可以适当地设置它。如:

initialize: function () {
        var self = this;
        self.spaces = new Space.Collection(bootstrapData.spaces);

        self.listenTo(self.spaces, 'figureMoved', self.updateFigurePosition);
        gameService.addHandler('figureMoved', function (figureId, spaceId, drawFigure) {
            self.updateFigurePosition(figureId, spaceId, drawFigure);
        });
    },

我仍然想知道在所有情况下这是否都是可行的解决方案。似乎奇怪,我必须将我的函数包装在另一个函数中,这样我才能引用我想要的变量。但是我怀疑这对于信号器,主干或者需要更多的问题以及对于J#派对迟到的C#家伙来说仍然存在问题,并且仍然会在某些语言的“功能”上发现。

相关问题