我正在嘗試使用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;
});