├── .gitignore ├── bg.png ├── screenshot.png ├── config.example.json ├── multi-insert.sh ├── .gitmodules ├── Readme.markdown ├── server.js └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | tmp/ 4 | config.json 5 | -------------------------------------------------------------------------------- /bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karmi/visualizing-couchdb-changes-with-node-js/HEAD/bg.png -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karmi/visualizing-couchdb-changes-with-node-js/HEAD/screenshot.png -------------------------------------------------------------------------------- /config.example.json: -------------------------------------------------------------------------------- 1 | config = { 2 | app : { 3 | port : 8000, 4 | host : '0.0.0.0' 5 | }, 6 | couchdb : { 7 | host : 'localhost', 8 | port : '5984', 9 | db : 'test', 10 | options : { include_docs:true } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /multi-insert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "\n\e[1mInserting 500 documents into http://localhost:5984/test. Stop me with Ctrl+C.\e[0m\n\n" 4 | 5 | for i in {1..5000} 6 | do 7 | curl -s -H 'Content-Type: application/json' -X POST http://localhost:5984/test -d '{"foo":"bar"}' 8 | done 9 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/node-couchdb"] 2 | path = lib/node-couchdb 3 | url = https://github.com/felixge/node-couchdb.git 4 | [submodule "lib/socket.io"] 5 | path = lib/socket.io 6 | url = http://github.com/LearnBoost/Socket.IO.git 7 | [submodule "lib/socket.io-node"] 8 | path = lib/socket.io-node 9 | url = http://github.com/LearnBoost/Socket.IO-node.git 10 | -------------------------------------------------------------------------------- /Readme.markdown: -------------------------------------------------------------------------------- 1 | # Visualizing CouchDB Database Changes with Node.js and Sockets # 2 | 3 | An experiment in basic real-time visualization of _CouchDB_ [`_changes` stream](http://guide.couchdb.org/draft/notifications.html) 4 | with [_Node.js_](http://nodejs.org/) and [Socket.IO](http://socket.io/). 5 | 6 | ![Screenshot: Realtime visualization of CouchDB _changes with Node.js](https://github.com/karmi/visualizing-couchdb-changes-with-node-js/raw/master/screenshot.png) 7 | 8 | ## Installation ## 9 | 10 | Clone the repository and navigate into it: 11 | 12 | $ git clone git://github.com/karmi/visualizing-couchdb-changes-with-node-js.git couchdb-changes 13 | $ cd couchdb-changes 14 | 15 | Initialize the submodules: 16 | 17 | $ git submodule update --init 18 | 19 | Copy (and posibly edit) the configuration file (it listens on by default): 20 | 21 | $ cp config.example.json config.json 22 | 23 | Start the _Node.js_ server: 24 | 25 | $ node server.js 26 | 27 | Open the client [application](http://localhost:8000/) in browser: 28 | 29 | $ open http://localhost:8000/ 30 | 31 | Now make some changes in the database and see them in you browser, instantly: 32 | 33 | $ curl -H 'Content-Type: application/json' -X POST http://localhost:5984/test -d '{"foo":"bar"}' 34 | 35 | ----- 36 | 37 | [Karel Minarik](http://karmi.cz) 38 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | require.paths.unshift('./lib/node-couchdb/lib/', 2 | './lib/socket-io/lib/', 3 | './lib/socket.io-node/lib/'); 4 | 5 | require('./config.json') 6 | 7 | var http = require('http'), 8 | url = require('url'), 9 | io = require('socket.io'), 10 | couchdb = require('couchdb'), 11 | sys = require('sys'), 12 | fs = require('fs'); 13 | 14 | var client = couchdb.createClient(config.couchdb.port, config.couchdb.host), 15 | db = client.db(config.couchdb.db); 16 | 17 | // -- Connect to _changes and attach passed callback -------------------------- 18 | 19 | var attach_couchdb_changes_stream = function(callback) { 20 | var stream, 21 | since; 22 | 23 | db.info(function(err, data) { 24 | if (err) throw new Error(JSON.stringify(err)); 25 | // Get 'update_seq' from database info and use it for 'since' param 26 | since = data.update_seq; 27 | stream = db.changesStream({since:since}); 28 | console.log('db.update_seq: ' + since); 29 | 30 | // Attach callback for socket.io 31 | stream.addListener('data', callback); 32 | }); 33 | 34 | return stream; 35 | } 36 | 37 | 38 | // -- Node.js Server ---------------------------------------------------------- 39 | 40 | server = http.createServer(function(req, res){ 41 | var path = url.parse(req.url).pathname; 42 | 43 | switch (path) { 44 | case '/': 45 | res.writeHead(200, {'Content-Type': 'text/html'}) 46 | fs.readFile(__dirname + '/index.html', function(err, data){ 47 | res.write(data, 'utf8'); 48 | res.end(); 49 | }); 50 | break; 51 | case '/config.json': 52 | res.writeHead(200, {'Content-Type': 'text/javascript'}) 53 | fs.readFile(__dirname + '/config.json', function(err, data){ 54 | res.write(data, 'utf8'); 55 | res.end(); 56 | }); 57 | case '/bg.png': 58 | res.writeHead(200, {'Content-Type': 'image/png'}) 59 | fs.readFile(__dirname + '/bg.png', function(err, data){ 60 | res.write(data); 61 | res.end(); 62 | }); 63 | break; 64 | }; 65 | }) 66 | server.listen(config.app.port, config.app.host); 67 | 68 | 69 | // -- Setup Socket.IO --------------------------------------------------------- 70 | 71 | var io = io.listen(server); 72 | 73 | io.on('connection', function(client){ 74 | // console.log('Client connected:', sys.inspect(client)); 75 | 76 | // Send CouchDB connection info 77 | client.send(db) 78 | 79 | // Send CouchDB _changes 80 | attach_couchdb_changes_stream(function(change) { 81 | client.send(change) 82 | }); 83 | 84 | }); 85 | 86 | console.log('Server running at http://'+config.app.host+':'+config.app.port+'/'); 87 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CouchDB Changes 5 | 6 | 7 | 8 | 9 | 10 | 62 | 63 | 64 | 65 |
66 |
67 |
68 |
69 |
0
70 |

71 |
72 |
73 |
74 |
75 | 76 | 77 | 78 | 222 | 223 | 224 | 225 | --------------------------------------------------------------------------------