How to manage and selectively stop a published subscription from Meteor server side code -


i'm developing competitive turn based game. when anonymous visitor visits page, automatically subscribing non-full instance of game can either observe or join action. there limited number of spots in each game instance. when joining game (taking spot), old subscription stopped , new 1 created includes private information based on chosen spot. far good.

now want make server free spot whenever player doesn't complete turn in reasonable amount of time.

the question how can make sure player kicked out of spot no longer receives updates intended go else occupying spot? has happen on server side clients cannot trusted. ideally kicked out user seamlessly become observer again.

i know there method stop() can called inside publish(), how use stop published subscription 1 particular client when callback set meteor.settimeout() gets called on server?

some heavily modified code of i'm trying (not meant work, give idea)

  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) 

create 2 separate subscriptions both return game data. 1 subscription should return public game data, other should return game data viewable currentuser. merged 1 collection on client side. games user has joined contain private info , public info, games haven't joined contain public info. on client side, livequery game.findone(thisgame.id) automatically receive private information when player joins game , cause template re-rendered, etc.

pseudo-code illustrative purposes:

if meteor.isclient   meteor.subscribe 'gameinstances'   meteor.subscribe 'mygameinstances', guestid    join = (gameinstanceid, spot) ->       meteor.call "join", gameinstanceid, spot, (err, guestid) ->           session.set("guestid", guestid)  if meteor.isserver     meteor.publish 'gameinstances', () ->        secretfields = {spots.guestid:false, spots.privategameinfo:false}        gameinstances.find {openspots: {$gt: 0}}, {fields: secretfields}     meteor.publish 'mygameinstances', (guestid) ->        gameinstances.find {'spots.guestid': guestid}, {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 = () ->                gameinstance.removeplayer(nextplayer.guestid)            gameinstance.timer = meteor.settimeout(kick, 60000) 

it sounds might including many players private info on 1 game instance. harder filter fields allowed (and publish current guest's private info, without publishing other players' private info).

in case, might consider either:

  • refactor private info separate collection, , publish separate subscription
  • custom publish function. here's example:

https://gist.github.com/colllin/8321227

in code, i'm observing 1 collection , publishing data merged meteor.users collection. can see subscription publishing data {_id: userid, wins: 25}, makes wins field available on user models on client side. want observe() games collection manually filter private data based on current user, publish private data games collection merged public data. can pass in guestid publish function did above.


Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -