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
Post a Comment