Skip to content

Instantly share code, notes, and snippets.

@digitarald
Created November 13, 2012 00:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save digitarald/c3bb16b1989209801535 to your computer and use it in GitHub Desktop.
Save digitarald/c3bb16b1989209801535 to your computer and use it in GitHub Desktop.
var express = require('express'),
app = express(express.logger());
// Set up express
app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
app.use(express.static(__dirname + '/static'));
app.use(express.bodyParser());
// CORS middle-ware
app.use(function(req, res, next) {
// the client should pass-through its origin
var origin = req.headers.origin || '*';
res.header('access-control-allow-origin', origin);
res.header('access-control-allow-methods', 'GET, POST, PUT, DELETE, OPTIONS')
res.header('access-control-allow-headers', 'Content-Type');
next();
});
// Twitter Streamer
var users = [];
var twitter = require('ntwitter');
var twit = new twitter({
...
});
var Streamer = {
started: false,
track: 'HTML5,WebAPI,FirefoxOS,JavaScript',
start: function() {
this.started = true;
twit.stream('statuses/filter', {
'track': this.track
}, function(stream) {
Streamer.stream = stream;
stream.on('data', function(data) {
if (!data.text) {
return;
}
// Reduce data to useful keys
var json = JSON.stringify({
id: data.id_str,
text: data.text,
created_at: data.created_at,
retweets: data.retweet_count,
user: data.user.screen_name,
user_name: data.user.name,
user_img: data.user.profile_image_url
});
// Write data to all active event users
var i = users.length;
while (i--) {
var channel = users[i];
channel.write('event: tweet\n');
channel.write('data: ' + json + '\n\n');
}
});
stream.on('end', function(response) {
Streamer.started = false;
Streamer.stream = null;
});
stream.on('destroy', function(response) {
// Handle a 'silent' disconnection from Twitter
Streamer.started = false;
Streamer.stream = null;
});
});
}
};
// Example index
app.get('/', function(req, res) {
res.render('index');
});
// Events handler
app.get('/events', function(req, res) {
// Setup event channel
res.type('text/event-stream');
res.write('event: hello\n');
res.write('data: ' + JSON.stringify({track: Streamer.track}) + '\n\n');
// A new user
users.push(res);
console.log('Connected user ' + users.length);
var onEnd = function() {
var pos = users.indexOf(res);
if (pos !== -1) {
console.log('Removing %d', pos);
users.splice(pos, 1);
}
};
req.on('close', onEnd); // request closed unexpectedly
// req.on('end', onEnd); // request ended normally
if (!Streamer.started) {
Streamer.start();
}
});
var port = 8080;
// WebSocket handler and server
var wsockets = [];
var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({port: port, debug: true});
wss.on('connection', function(ws) {
var uid = wsockets.push(ws);
var broadcast = function(message) {
wsockets.forEach(function(other_ws) {
if (other_ws == ws) {
return;
}
other_ws.send(message);
});
};
ws.on('message', function(message) {
console.log('message', message);
broadcast(message);
});
ws.on('close', function() {
wsockets.splice(wsockets.indexOf(ws), 1);
broadcast(JSON.stringify({
event: 'left',
count: wsockets.length
}));
});
broadcast(JSON.stringify({
event: 'joined',
count: wsockets.length
}));
});
// Start web server
app.listen(port, function() {
console.log('Listening on ' + port);
});
var Chat = {
init: function() {
this.$output = $('#chat-output');
var host = location.host.replace(/:.*/, '');
console.log('Connecting to ' + host);
var ws = new WebSocket('ws://' + host);
ws.onmessage = function (event) {
var data = JSON.parse(event.data);
switch (data.event) {
case 'joined':
Chat.appendMessage('One more, now we are ' + data.count, 'count');
break;
case 'left':
Chat.appendMessage('One down, ' + data.count + ' remaining', 'count');
break;
case 'broadcast':
Chat.appendMessage(data.text);
break;
}
};
ws.onclose = function (event) {
Chat.appendMessage('Connection lost', 'count');
};
$('#chat-input').on('submit', function(evt) {
evt.preventDefault();
var $input = $(this).find('input')
var value = $input.val();
if (value) {
console.log(value);
ws.send(JSON.stringify({
event: 'broadcast',
text: value
}));
Chat.appendMessage(value, 'own');
}
$input.val('')[0].focus();
});
},
appendMessage: function(message, cls) {
var $entry = $('<div class="chat-line">').text(message);
Chat.$output.append($entry);
if (cls) {
$entry.addClass(cls);
}
// Truncate
while (Chat.$output.children().size() > 15) {
Chat.$output.children().last().remove();
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment