mirror of
https://github.com/fergalmoran/dss-realtime.git
synced 2025-12-22 09:38:06 +00:00
First commit
This commit is contained in:
13
.editorconfig
Normal file
13
.editorconfig
Normal file
@@ -0,0 +1,13 @@
|
||||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
28
.gitignore
vendored
Normal file
28
.gitignore
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directory
|
||||
# Deployed apps should consider commenting this line out:
|
||||
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
|
||||
node_modules
|
||||
bower_components
|
||||
.idea
|
||||
.DS_Store
|
||||
21
.jshintrc
Normal file
21
.jshintrc
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"node": true,
|
||||
"esnext": true,
|
||||
"bitwise": true,
|
||||
"camelcase": true,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"immed": true,
|
||||
"indent": 4,
|
||||
"latedef": true,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"quotmark": "single",
|
||||
"regexp": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"strict": true,
|
||||
"trailing": true,
|
||||
"smarttabs": true,
|
||||
"white": true
|
||||
}
|
||||
2
.nodemonignore
Normal file
2
.nodemonignore
Normal file
@@ -0,0 +1,2 @@
|
||||
# Generated by grunt-nodemon
|
||||
node_modules/**
|
||||
210
Gruntfile.js
Normal file
210
Gruntfile.js
Normal file
@@ -0,0 +1,210 @@
|
||||
// Generated on 2014-08-23 using generator-socketio 0.0.3
|
||||
'use strict';
|
||||
var moment = require('moment');
|
||||
|
||||
var LIVERELOAD_PORT = 35729;
|
||||
var RUNNING_PORT = 8001; // <- if you change this, you need to change in public/js/app.js and recompile
|
||||
var lrSnippet = require('connect-livereload')({port: LIVERELOAD_PORT});
|
||||
var mountFolder = function (connect, dir) {
|
||||
return connect.static(require('path').resolve(dir));
|
||||
};
|
||||
|
||||
module.exports = function (grunt) {
|
||||
// load all grunt tasks
|
||||
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
|
||||
|
||||
grunt.initConfig({
|
||||
|
||||
cssmin: {
|
||||
combine: {
|
||||
files: {
|
||||
'public/css/core.css': 'public/bower_components/bootstrap.css/css/bootstrap.css'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
less: {
|
||||
options: {
|
||||
//report:'gzip'
|
||||
},
|
||||
production: {
|
||||
options: {
|
||||
cleancss: true
|
||||
},
|
||||
files: {
|
||||
"public/css/core.css": "public/bower_components/bootstrap/less/bootstrap.less"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
sass: {
|
||||
dist: {
|
||||
options: {
|
||||
style: 'compressed'
|
||||
},
|
||||
files: {
|
||||
'public/css/core.css': 'public/bower_components/sass-bootstrap/lib/bootstrap.scss',
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
stylus: {
|
||||
compile: {
|
||||
options: {
|
||||
compress:true
|
||||
},
|
||||
files: {
|
||||
'public/css/core.css': 'public/bower_components/bootstrap-stylus/stylus/bootstrap.styl'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
concat: {
|
||||
options: {
|
||||
separator: ';',
|
||||
stripBanners:true
|
||||
},
|
||||
dist: {
|
||||
src: ['public/js/app.js'],
|
||||
dest: 'public/js/concat.js',
|
||||
},
|
||||
},
|
||||
|
||||
//this is currently turned off, since jquery KILLS it
|
||||
jshint: {
|
||||
options: {
|
||||
curly: true,
|
||||
eqeqeq: false,
|
||||
eqnull: true,
|
||||
browser: true,
|
||||
globals: {
|
||||
jQuery: true
|
||||
}
|
||||
},
|
||||
files:{
|
||||
src:['public/js/concat.js']
|
||||
}
|
||||
},
|
||||
|
||||
uglify: {
|
||||
options: {
|
||||
mangle: false
|
||||
},
|
||||
my_target: {
|
||||
files: {
|
||||
'public/js/app.min.js': ['public/js/concat.js']
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Watch Config
|
||||
watch: {
|
||||
files: ['views/**/*'],
|
||||
options: {
|
||||
livereload: true
|
||||
},
|
||||
scripts: {
|
||||
files: [
|
||||
'public/js/**/*.js'
|
||||
],
|
||||
tasks:['build']
|
||||
},
|
||||
css: {
|
||||
files: [
|
||||
'public/css/**/*.css',
|
||||
],
|
||||
},
|
||||
less: {
|
||||
files: ['public/bower_components/bootstrap/less/**/*.less'],
|
||||
tasks: ['build']
|
||||
},
|
||||
express: {
|
||||
files: [ 'server.js', '!**/node_modules/**', '!Gruntfile.js' ],
|
||||
tasks: [ 'watch' ],
|
||||
options: {
|
||||
nospawn: true // Without this option specified express won't be reloaded
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
connect: {
|
||||
options: {
|
||||
port: RUNNING_PORT,//variable at top of this file
|
||||
// change this to '0.0.0.0' to access the server from outside
|
||||
hostname: 'localhost'
|
||||
},
|
||||
livereload: {
|
||||
options: {
|
||||
middleware: function (connect) {
|
||||
return [
|
||||
lrSnippet,
|
||||
mountFolder(connect, '.')
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
nodemon:{
|
||||
dev: {
|
||||
options: {
|
||||
file: 'server.js',
|
||||
//args: ['dev'],
|
||||
//nodeArgs: ['--debug'],
|
||||
ignoredFiles: ['node_modules/**'],
|
||||
//watchedExtensions: ['js'],
|
||||
watchedFolders: ['views', 'routes'],
|
||||
//delayTime: 1,
|
||||
legacyWatch: true,
|
||||
env: {
|
||||
PORT: RUNNING_PORT
|
||||
},
|
||||
cwd: __dirname
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// run 'watch' and 'nodemon' indefinitely, together
|
||||
// 'launch' will just kick it off, and won't stay running
|
||||
concurrent: {
|
||||
target: {
|
||||
tasks: ['nodemon', 'watch', 'launch'],
|
||||
options: {
|
||||
logConcurrentOutput: true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
wait:{
|
||||
options: {
|
||||
delay: 1000
|
||||
},
|
||||
pause:{
|
||||
options:{
|
||||
before:function(options){
|
||||
console.log('pausing %dms before launching page', options.delay);
|
||||
},
|
||||
after : function() {
|
||||
console.log('pause end, heading to page (using default browser)');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
open: {
|
||||
server: {
|
||||
path: 'http://localhost:' + RUNNING_PORT
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
//grunt.registerTask('server', ['build', 'connect:livereload', 'open', 'watch']);
|
||||
|
||||
grunt.registerTask('build', ['cssmin', 'concat', 'uglify']);
|
||||
|
||||
grunt.registerTask('launch', ['wait', 'open']);
|
||||
|
||||
grunt.registerTask('default', ['build', 'concurrent']);
|
||||
|
||||
};
|
||||
7
bower.json
Normal file
7
bower.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "dss-realtime",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"bootstrap.css": "~2.3.2"
|
||||
}
|
||||
}
|
||||
42
package.json
Normal file
42
package.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "dss-realtime",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"version": "0.0.1",
|
||||
"main": "server.js",
|
||||
"private": true,
|
||||
"repository": "",
|
||||
"dependencies": {
|
||||
"body-parser": "*",
|
||||
"connect": "*",
|
||||
"cookie": "^0.1.2",
|
||||
"cookie-parser": "*",
|
||||
"express": "*",
|
||||
"express-session": "*",
|
||||
"jade": "*",
|
||||
"socket.io": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"grunt": "~0.4.1",
|
||||
"bower": "~0.9.2",
|
||||
"grunt-concurrent": "~0.4.2",
|
||||
"grunt-nodemon": "~0.1.2",
|
||||
"grunt-contrib-connect": "~0.2.0",
|
||||
"grunt-contrib-cssmin": "^0.9.0",
|
||||
"grunt-contrib-less": "~0.8.2",
|
||||
"grunt-contrib-sass": "~0.6.0",
|
||||
"grunt-contrib-stylus": "~0.11.0",
|
||||
"grunt-contrib-watch": "~0.5.3",
|
||||
"grunt-contrib-jshint": "~0.8.0",
|
||||
"grunt-contrib-concat": "~0.3.0",
|
||||
"grunt-contrib-uglify": "~0.2.7",
|
||||
"grunt-open": "~0.2.2",
|
||||
"grunt-wait": "~0.1.0",
|
||||
"matchdep": "~0.1.2",
|
||||
"connect-livereload": "~0.1.3",
|
||||
"moment": "~2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
}
|
||||
9
public/css/core.css
Normal file
9
public/css/core.css
Normal file
File diff suppressed because one or more lines are too long
54
public/js/app.js
Normal file
54
public/js/app.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/*************************************
|
||||
//
|
||||
// dss-realtime app
|
||||
//
|
||||
**************************************/
|
||||
|
||||
// connect to our socket server
|
||||
var socket = io.connect('http://127.0.0.1:8001/');
|
||||
|
||||
var app = app || {};
|
||||
|
||||
|
||||
// shortcut for document.ready
|
||||
$(function(){
|
||||
//setup some common vars
|
||||
var $blastField = $('#blast'),
|
||||
$allPostsTextArea = $('#allPosts'),
|
||||
$clearAllPosts = $('#clearAllPosts'),
|
||||
$sendBlastButton = $('#send');
|
||||
|
||||
|
||||
//SOCKET STUFF
|
||||
socket.on("blast", function(data){
|
||||
var copy = $allPostsTextArea.html();
|
||||
$allPostsTextArea.html('<p>' + copy + data.msg + "</p>");
|
||||
$allPostsTextArea.scrollTop($allPostsTextArea[0].scrollHeight - $allPostsTextArea.height());
|
||||
//.css('scrollTop', $allPostsTextArea.css('scrollHeight'));
|
||||
|
||||
});
|
||||
|
||||
$clearAllPosts.click(function(e){
|
||||
$allPostsTextArea.text('');
|
||||
});
|
||||
|
||||
$sendBlastButton.click(function(e){
|
||||
|
||||
var blast = $blastField.val();
|
||||
if(blast.length){
|
||||
socket.emit("blast", {msg:blast},
|
||||
function(data){
|
||||
$blastField.val('');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
$blastField.keydown(function (e){
|
||||
if(e.keyCode == 13){
|
||||
$sendBlastButton.trigger('click');//lazy, but works
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
1
public/js/app.min.js
vendored
Normal file
1
public/js/app.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
var socket=io.connect("http://127.0.0.1:8001/"),app=app||{};$(function(){var $blastField=$("#blast"),$allPostsTextArea=$("#allPosts"),$clearAllPosts=$("#clearAllPosts"),$sendBlastButton=$("#send");socket.on("blast",function(data){var copy=$allPostsTextArea.html();$allPostsTextArea.html("<p>"+copy+data.msg+"</p>"),$allPostsTextArea.scrollTop($allPostsTextArea[0].scrollHeight-$allPostsTextArea.height())}),$clearAllPosts.click(function(){$allPostsTextArea.text("")}),$sendBlastButton.click(function(){var blast=$blastField.val();blast.length&&socket.emit("blast",{msg:blast},function(){$blastField.val("")})}),$blastField.keydown(function(e){13==e.keyCode&&$sendBlastButton.trigger("click")})});
|
||||
48
public/js/concat.js
Normal file
48
public/js/concat.js
Normal file
@@ -0,0 +1,48 @@
|
||||
// connect to our socket server
|
||||
var socket = io.connect('http://127.0.0.1:8001/');
|
||||
|
||||
var app = app || {};
|
||||
|
||||
|
||||
// shortcut for document.ready
|
||||
$(function(){
|
||||
//setup some common vars
|
||||
var $blastField = $('#blast'),
|
||||
$allPostsTextArea = $('#allPosts'),
|
||||
$clearAllPosts = $('#clearAllPosts'),
|
||||
$sendBlastButton = $('#send');
|
||||
|
||||
|
||||
//SOCKET STUFF
|
||||
socket.on("blast", function(data){
|
||||
var copy = $allPostsTextArea.html();
|
||||
$allPostsTextArea.html('<p>' + copy + data.msg + "</p>");
|
||||
$allPostsTextArea.scrollTop($allPostsTextArea[0].scrollHeight - $allPostsTextArea.height());
|
||||
//.css('scrollTop', $allPostsTextArea.css('scrollHeight'));
|
||||
|
||||
});
|
||||
|
||||
$clearAllPosts.click(function(e){
|
||||
$allPostsTextArea.text('');
|
||||
});
|
||||
|
||||
$sendBlastButton.click(function(e){
|
||||
|
||||
var blast = $blastField.val();
|
||||
if(blast.length){
|
||||
socket.emit("blast", {msg:blast},
|
||||
function(data){
|
||||
$blastField.val('');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
$blastField.keydown(function (e){
|
||||
if(e.keyCode == 13){
|
||||
$sendBlastButton.trigger('click');//lazy, but works
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
91
server.js
Normal file
91
server.js
Normal file
@@ -0,0 +1,91 @@
|
||||
/*************************************
|
||||
//
|
||||
// dss-realtime app
|
||||
//
|
||||
**************************************/
|
||||
|
||||
var express = require('express'), http = require('http'), connect = require('connect'), bodyParser = require('body-parser'), session = require('express-session'), cookieParser = require('cookie-parser'), cookie_reader = require('cookie'), io = require('socket.io');
|
||||
|
||||
var app = express();
|
||||
var sessionStore = new connect.session.MemoryStore();
|
||||
var SITE_SECRET = 'I am not wearing any pants';
|
||||
var SITE_KEY = 'express.sid';
|
||||
app.use(bodyParser());
|
||||
app.use(cookieParser(SITE_SECRET));
|
||||
app.use(session({
|
||||
store: sessionStore,
|
||||
key: SITE_KEY,
|
||||
secret: SITE_SECRET
|
||||
}));
|
||||
|
||||
var port = app.get('port') || 8001;
|
||||
|
||||
var server = http.createServer(app);
|
||||
server.listen(port, function () {
|
||||
console.log("Express server listening on port " + port);
|
||||
});
|
||||
|
||||
/**
|
||||
* Socket.io
|
||||
*/
|
||||
var sio = io.listen(server);
|
||||
var sessions = {};
|
||||
var clients = {};
|
||||
sio.use(function ioSession(socket, next) {
|
||||
// create the fake req that cookieParser will expect
|
||||
var req = {
|
||||
"headers": {
|
||||
"cookie": socket.request.headers.cookie
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
sio.set('authorization', function (data, accept) {
|
||||
//create fake req object to pass to cookie parser
|
||||
if (data.headers.cookie) {
|
||||
data.cookie = cookie_reader.parse(data.headers.cookie);
|
||||
return accept(null, true);
|
||||
}
|
||||
return accept('error', false);
|
||||
});
|
||||
|
||||
sio.sockets.on('connection', function (socket) {
|
||||
var hs = socket.handshake;
|
||||
console.log('A socket with sessionID ' + hs.sessionID + ' connected.');
|
||||
|
||||
var cookie = cookie_reader.parse(socket.handshake.headers.cookie);
|
||||
|
||||
sessions[cookie['sessionid']] = socket.id;
|
||||
clients[socket.id] = socket;
|
||||
|
||||
socket.on('disconnect', function () {
|
||||
delete clients[socket.id]; // remove the client from the array
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Web Server
|
||||
*/
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
|
||||
//set the view engine
|
||||
app.set('view engine', 'ejs');
|
||||
app.set('views', __dirname + '/views');
|
||||
|
||||
app.get("/", function (req, res) {
|
||||
res.render('index', {});
|
||||
});
|
||||
|
||||
app.post("/notification", function (req, res) {
|
||||
if (sessions[req.body.sessionid]) {
|
||||
console.log("Data is: " + req.body.message);
|
||||
clients[sessions[req.body.sessionid]].emit('notification', {message: req.body.message});
|
||||
res.send(req.body);
|
||||
}else{
|
||||
res.send(404);
|
||||
}
|
||||
});
|
||||
83
views/index.ejs
Normal file
83
views/index.ejs
Normal file
@@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>dss-realtime</title>
|
||||
<meta name="description" content="Dss Realtime Host">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="stylesheet" href="css/core.css">
|
||||
|
||||
<style>
|
||||
|
||||
input:focus,
|
||||
select:focus,
|
||||
textarea:focus,
|
||||
button:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
#allPosts {
|
||||
resize: none;
|
||||
font-size: 12px;
|
||||
border-radius: 5px;
|
||||
border: #ccc solid 1px;
|
||||
line-height: 14px;
|
||||
height:100px;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
p{
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!--[if lt IE 8]>
|
||||
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
|
||||
<![endif]-->
|
||||
|
||||
<div class="container">
|
||||
<div class="jumbotron">
|
||||
<h1>dss-realtime</h1>
|
||||
<p>Dss Realtime Host</p>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-sm-6 col-xs-6">
|
||||
<h3>All Chatter<button id="clearAllPosts" type="button" class="btn btn-danger btn-xs pull-right">clear</button></h3>
|
||||
<div id="allPosts" class="form-control"></div>
|
||||
<div class="input-group">
|
||||
<input id="blast" type="text" class="form-control" placeholder="send something to everyone">
|
||||
<span class="input-group-btn">
|
||||
<button id="send" class="btn btn-success" type="button">Send</button>
|
||||
</span>
|
||||
</div><!-- /input-group -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
|
||||
<script>window.jQuery || document.write('<script src="public/bower_components/jQuery/jquery.min.js"><\/script>')</script>
|
||||
|
||||
<!-- socket.io -->
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
|
||||
<!-- APP CODE -->
|
||||
<script src="js/app.min.js"></script>
|
||||
|
||||
<!-- Google Analytics: change UA-XXXXX-X to be your site's ID. -->
|
||||
<script>
|
||||
(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
|
||||
function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
|
||||
e=o.createElement(i);r=o.getElementsByTagName(i)[0];
|
||||
e.src='//www.google-analytics.com/analytics.js';
|
||||
r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
|
||||
ga('create','UA-XXXXX-X');ga('send','pageview');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
32
views/index.jade
Normal file
32
views/index.jade
Normal file
@@ -0,0 +1,32 @@
|
||||
doctype 5
|
||||
html
|
||||
head
|
||||
title SessionSockets usage example
|
||||
script(type='text/javascript', src='/socket.io/socket.io.js')
|
||||
style(type='text/css')
|
||||
body
|
||||
padding: 30px 50px;
|
||||
#t {
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
outline: none;
|
||||
width: 700px;
|
||||
height: 100px;
|
||||
}
|
||||
#foo {
|
||||
width: 200px;
|
||||
}
|
||||
body
|
||||
h1 SessionSockets usage example
|
||||
p='You should see below your session hash with "bar" as initial value for the "foo" key'
|
||||
textarea#t(readonly='1')
|
||||
input#foo(placeholder='now type in a new value for foo')
|
||||
span=' then you should see foo value updated'
|
||||
script(type='text/javascript')
|
||||
var socket = io.connect();
|
||||
socket.on('session', function (session) {
|
||||
document.getElementById('t').value = JSON.stringify(session);
|
||||
});
|
||||
document.getElementById('foo').addEventListener('keyup', function () {
|
||||
socket.emit('foo', this.value);
|
||||
});
|
||||
Reference in New Issue
Block a user