title: How to manage and selectively stop a published subscription from Meteor server side code
body: <p>I'm developing a competitive turn based game. When an anonymous visitor visits a page, he is automatically subscribing to a non-full instance of the game he can then either just observe or join the action. There are limited number of spots in each game instance. When joining the game (taking up a spot), the old subscription is stopped and new one is created that also includes private information based on his chosen spot. So far so good.</p>
  
  <p>Now I want to make the server free up a spot whenever a player doesn't complete his turn in reasonable amount of time.</p>
  
  <p>The question is how can I make sure the player kicked out of his spot no longer receives updates that are now intended to go to someone else occupying his spot? Obviously this has to happen on server side as clients cannot be trusted. Ideally the kicked out user would seamlessly become the observer again.</p>
  
  <p>I know there is a method <em>stop()</em> that can be called inside <em>publish()</em>, but how to use it to stop a published subscription for one particular client when a callback set by <em>Meteor.setTimeout()</em> gets called on the server?</p>
  
  <p>Some heavily modified code of what I'm trying to do (not meant to work, only to give you an idea)</p>
  
  <pre><code>  if Meteor.isClient
        publicGameHandle = Meteor.subscribe 'GameInstances'
  
        join = (gameInstanceId, spot) -&gt;
            Meteor.call "join", gameInstanceId, spot, (err, guestId) -&gt;
                Session.set("guestId", guestId)
                privateGameHandle = Meteor.subscribe 'GameInstances',
                gameInstanceId, spot, guestId, -&gt;
                    publicGameHandle.stop()
  
     if Meteor.isServer
         privateSubscriptions = {}
  
         Meteor.publish 'GameInstances', (gameInstanceId, spot, guestId) -&gt;
             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) -&gt;
                 guestId = Random.id()
                     gameInstances[gameInstanceId].addPlayer(spot, guestId)
                 guestId
  
             completePlayerTurn: (gameInstanceId, spot, guestId) -&gt;
                 gameInstance = gameInstances[gameInstanceId]
                 Meteor.clearTimeout(gameInstance.timer)
                 nextPlayer = gameInstance.getNextPlayer()
  
                 kick = () -&gt;
                     privateSubcriptions[nextPlayer.guestId].stop()
                     gameInstance.removePlayer(nextPlayer.guestId)
                 gameinstance.timer = Meteor.setTimeout(kick, 60000)
  </code></pre>