## Browser

    // [...] - boilerplate code to connect to Crossbar.io

    function main (session) {
       // subscribe to future vote event
       session.subscribe("io.crossbar.demo.vote.onvote",
          function(args, kwargs, details) {
             var event = args[0];
             document.getElementById("votes" + event.subject).value =
                event.votes;
          });

       // get the current vote count
       session.call("io.crossbar.demo.vote.get").then(
          function(res){
             for(var i = 0; i < res.length; i++) {
                document.getElementById("votes" + res[i].subject).value =
                   res[i].votes;
             }
       }, session.log);

       // wire up vote buttons
       var voteButtons = document.getElementById("voteContainer").
                                  getElementsByTagName("button");
       for (var i = 0; i < voteButtons.length; i++) {
          voteButtons[i].onclick = function(evt) {
             session.call("io.crossbar.demo.vote.vote",
                [evt.target.id]).then(session.log, session.log);
          };
       }

       // subscribe to vote reset event
       session.subscribe("io.crossbar.demo.vote.onreset", function() {
             var voteCounters = document.getElementById("voteContainer").
                                         getElementsByTagName("input");
             for(var i = 0; i < voteCounters.length; i++) {
                voteCounters[i].value = 0;
             }
          });

       // wire up reset button
       document.getElementById("resetVotes").onclick = function() {
          session.call("io.crossbar.demo.vote.reset").
             then(session.log, session.log);
       };
    }

## Node.js

    // [...] - boilerplate code to connect to Crossbar.io

    function main (session) {

       // return set of present votes on request
       var getVote = function() {
          var votesArr = [];
          for (var flavor in votes) {
             if (votes.hasOwnProperty(flavor)) {
                votesArr.push({
                   subject: flavor,
                   votes: votes[flavor]
                })
             }
          }
          return votesArr;
       };

       // handle vote submission
       var submitVote = function(args, kwargs, details) {
          var flavor = args[0];
          votes[flavor] += 1;

          var res = {
             subject: flavor,
             votes: votes[flavor]
          };

          // publish the vote event
          session.publish("io.crossbar.demo.vote.onvote", [res]);

          return "voted for " + flavor;
       };

       // reset vote count
       var resetVotes = function() {
          for (var fl in votes) {
             if (votes.hasOwnProperty(fl)) {
                votes[fl] = 0;
             }
          }
          // publish the reset event
          session.publish("io.crossbar.demo.vote.onreset");
          return "votes reset";
       };

       // register the procedures
       session.register('io.crossbar.demo.vote.get', getVote);
       session.register('io.crossbar.demo.vote.vote', submitVote);
       session.register('io.crossbar.demo.vote.reset', resetVotes);
    }