我正在开发一款竞技回合制游戏。当匿名访问者访问一个页面时,他会自动订阅一个非完整的游戏实例,然后他可以观察或加入该动作。每个游戏实例中的点数有限。加入游戏(占用一个位置)时,旧订阅将停止并创建新订阅,其中还包括基于他选择的位置的私人信息。到目前为止,一切都很好。
现在我想在玩家没有在合理的时间内完成他的回合时让服务器腾出一个位置。
问题是我如何确保被踢出位置的玩家不再收到现在打算发送给占据他位置的其他人的更新?显然,这必须发生在服务器端,因为客户端不能被信任。理想情况下,被踢出的用户会再次无缝地成为观察者。
我知道有一个可以在publish()内部调用的方法stop( ) ,但是当Meteor.setTimeout()设置的回调在服务器上被调用时,如何使用它来停止一个特定客户端的已发布订阅?
我正在尝试做的一些经过大量修改的代码(不是为了工作,只是为了给你一个想法)
if Meteor.isClient
publicGameHandle = Meteor.subscribe 'GameInstances'
join = (gameInstanceId, spot) ->
Meteor.call "join", gameInstanceId, spot, (err, guestId) ->
Session.set("guestId", guestId)
privateGameHandle = Meteor.subscribe 'GameInstances',
gameInstanceId, spot, guestId, ->
publicGameHandle.stop()
if Meteor.isServer
privateSubscriptions = {}
Meteor.publish 'GameInstances', (gameInstanceId, spot, guestId) ->
if gameInstanceId
GameInstances.find {_id: gameInstanceId}
privateSubscriptions[guestId] = @
else
secretFields = {spots.guestId:false, spots.privateGameInfo:false}
GameInstances.find {openSpots: {$gt: 0}}, {fields: secretFields}
Meteor.methods({
join: (gameInstanceId, spot) ->
guestId = Random.id()
gameInstances[gameInstanceId].addPlayer(spot, guestId)
guestId
completePlayerTurn: (gameInstanceId, spot, guestId) ->
gameInstance = gameInstances[gameInstanceId]
Meteor.clearTimeout(gameInstance.timer)
nextPlayer = gameInstance.getNextPlayer()
kick = () ->
privateSubcriptions[nextPlayer.guestId].stop()
gameInstance.removePlayer(nextPlayer.guestId)
gameinstance.timer = Meteor.setTimeout(kick, 60000)