Pusher Websockets Example

by kyllle

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.2/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>
<script src="http://js.pusher.com/2.2/pusher.min.js"></script>
<h1>Sockets</h1>
<div class="js-app"></div>

<script type="text/template" class="tmpl-post">
    <b>{{author}}</b>
    <p>{{name}}</p>
    <p>{{title}}</p>
</script>

SCSS

@import url(http://fonts.googleapis.com/css?family=Raleway:400,700);

* {
  -webkit-font-smoothing: antialiased;
}

body {
    padding: 5%;
    font-family: Raleway;
    line-height: 1.4;
}

h1 {
    font-weight: bold;
    font-size: 24px;
    text-align: center;
}

p {
    margin: 4px 0;
}

.post {
    background: white;
    margin: 8px 0;
    box-shadow: 0 0 3px rgba(0,0,0,.2);
    padding: 8px;
}

JavaScript

console.clear();

/**
 *	What is this?
 *	Websocket demonstration using BackboneJS with Pusher to display
 *	real time posts being added on reddits askreddit subreddit :S.
 *	In order to decouple sockets from the application we store all
 *	socket related logic inside a socket adapter module which listens
 *	for subscribed server events and publishes events via the application
 *	event bus module.
 *
 *	Todos
 *	- Handle multiple objects coming down from server at one time.
 *	- What to do if the server response errors out?
 *	- Initial loader until posts begin to appear.
 *	- Where should the socket connection get initialised, on canvas initialise?
 *	- Stop connection on canvas dispose.
 */

var App = {
	M: {}, V: {}, C: {}, 
    utils: {}, 
    config: {
    	connectionId: '50ed18dd967b455393ed',
        channel: 'askreddit'
    },
    appEl: $('.js-app'),
	start: function() {
    	// Start socket adapter.
    	App.utils.socketAdapter();
        
        // Collection and View instances.
        var postsCollection = new this.C.Posts();
        var postsView = new this.V.PostsView({
        	collection: postsCollection
        });
        
        this.appEl.html(postsView.render().el);
    }
};

// Create centralised event bus.
App.utils.eventBus = _.extend({
	eventKeys: {
    	'SHOW_POST': 'show:post'
    },
    socketKeys: {
        'REDDIT_NEW_LISTING_BROADCAST': 'new-listing'
    }
}, Backbone.Events);

// Create the centralised socket adapter.
App.utils.socketAdapter = function() {

    var connection = new Pusher(App.config.connectionId),
    	channel = connection.subscribe(App.config.channel);

	channel.bind(App.utils.eventBus.socketKeys.REDDIT_NEW_LISTING_BROADCAST, function(data) {
        App.utils.eventBus.trigger(App.utils.eventBus.eventKeys.SHOW_POST, data);
    }.bind(this));
};

// Post Model
App.M.Post = Backbone.Model.extend();

// Posts Collection
App.C.Posts = Backbone.Collection.extend({
	model: App.M.Post,
    
    initialize: function()...