2013-06-02 52 views
1

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

回答

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

我仍然懷疑這是否可以成爲所有情況下可行的解決方案。似乎很奇怪,我必須將我的函數包裝在另一個函數中,以便我可以引用我想要的變量。但是我懷疑這對於信號集成,骨幹或者需求等問題來說並不是什麼問題,並且對於JavaScript派對來說遲到的C#人員來說更是如此,他們仍然對某些語言的「功能」感到不滿。

相關問題