Permalink
Browse files

example of mingled browser + cli chat program

  • Loading branch information...
1 parent 5f83903 commit 5bdc44718c6327472f74058336184fc7a195a437 @ahk committed Jul 26, 2010
@@ -0,0 +1,67 @@
+div#prompt {
+ width: 600px;
+ height: 400px;
+ margin: auto;
+ display: table-cell;
+ vertical-align: middle;
+ text-align: center;
+ background-color: rgb(30,30,30);
+ color: white;
+}
+
+div#chat {
+ width: 600px;
+ margin: auto;
+}
+
+div#messages {
+ display: none;
+ overflow-x: hidden;
+ overflow-y: scroll;
+ padding: 0.5em;
+ width: 600px;
+ height: 400px;
+ border-color: black;
+ border-style: solid;
+ border-width: 2px;
+ background-color: rgb(30,30,30);
+}
+
+form#post input {
+ width: 600px;
+ padding: 0.5em;
+ background-color: black;
+ color: white;
+ border-width: 0px;
+}
+
+span.who {
+ font-weight: bold;
+ margin-right: 1em;
+ color: rgb(200,200,200);
+}
+
+span.me {
+ font-weight: bold;
+ margin-right: 1em;
+ color: white;
+}
+
+span.msg {
+ color: white;
+}
+
+div.join {
+ color: rgb(200,250,150);
+ font-weight: bold;
+}
+
+div.part {
+ color: rgb(250,200,150);
+ font-weight: bold;
+}
+
+div.users {
+ color: rgb(150,200,250);
+ font-weight: bold;
+}
@@ -0,0 +1,109 @@
+<html>
+<head>
+<title>DNode Chat Example</title>
+<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
+<script type="text/javascript" src="/dnode.js"></script>
+<script type="text/javascript">
+ $(window).load(function () {
+ // Fetch the user's name before the main chat code fires
+ $('form#name').submit(function (ev) {
+ ev.preventDefault();
+ var name = $('input[name="name"]').val();
+ $('#messages').show();
+ $('#prompt').hide();
+ chat(name);
+ });
+ });
+
+ function chat (name) {
+ // Connect to the chat server now that we've got a name
+ DNode(function () {
+ this.name = function (f) { f(name) };
+
+ this.joined = function (who) {
+ addLine($('<div>')
+ .addClass('join')
+ .text(who + ' has joined')
+ );
+ };
+
+ this.parted = function (who) {
+ addLine($('<div>')
+ .addClass('part')
+ .text(who + ' has left')
+ );
+ };
+
+ this.said = function (who,msg) {
+ addLine($('<div>').append(
+ $('<span>')
+ .addClass(who == name ? 'me' : 'who')
+ .text('<' + who + '>')
+ ,
+ $('<span>').addClass('msg').text(msg)
+ ));
+ };
+
+ this.refreshNames = function (names) {
+ $('.users').text('Users: ' + (
+ names.map(function (name) {
+ return '[ ' + name
+ .replace(/\\/g,'\\\\')
+ .replace(/\[/g,'\\[')
+ .replace(/\]/g,'\\]')
+ + ' ]'
+ }).join(' ')
+ || '(no users)'
+ ));
+ };
+ }).connect(function (remote) {
+
+ $('form#post').submit(function (ev) {
+ ev.preventDefault();
+ remote.chat(this.elements.msg.value);
+ this.elements.msg.value = '';
+ });
+
+ // fetch a list of all the connected users
+ remote.names(function (names) {
+ addLine($('<div>')
+ .addClass('users')
+ .text('Users: ' + (
+ names.map(function (name) {
+ return '[ ' + name
+ .replace(/\\/g,'\\\\')
+ .replace(/\[/g,'\\[')
+ .replace(/\]/g,'\\]')
+ + ' ]'
+ }).join(' ')
+ || '(no users)'
+ ))
+ );
+ });
+ });
+ }
+
+ function addLine(elem) {
+ var div = $('#messages');
+ div.append(elem);
+ div.animate({ scrollTop: div.attr('scrollHeight') }, 200);
+ }
+</script>
+<link rel="StyleSheet" type="text/css" href="chat.css">
+</head>
+<body>
+ <div id="chat">
+ <div id="prompt">
+ <form id="name">
+ Name:
+ <input type="text" name="name">
+ </form>
+ </div>
+
+ <div id="messages"></div>
+
+ <form id="post">
+ <input type="text" name="msg">
+ </form>
+ </div>
+</body>
@@ -0,0 +1,102 @@
+#!/usr/bin/env node
+
+// imports
+var sys = require('sys');
+var DNode = require('dnode');
+// local
+var utils, cli;
+
+utils = {
+
+ slice: function (arr, start, opt_end) {
+ if (arguments.length <= 2) {
+ return Array.prototype.slice.call(arr, start);
+ } else {
+ return Array.prototype.slice.call(arr, start, opt_end);
+ }
+ }
+
+};
+
+cli = {
+
+ greeting: "Let's go fly a kite! (.quit or ctrl-D to quit)\n",
+
+ prompt: 'kite-string ~ ',
+
+ msgHeader: 'kiting ... ',
+
+ clientName: 'andrewcmd',
+
+ inspect: function(thingy) {
+ sys.debug(sys.inspect(thingy));
+ },
+
+ info: function() {
+ if (arguments.length == 0) {
+ return this.msgHeader;
+ }
+ var text = [];
+ text.push(this.msgHeader);
+ text.push(utils.slice(arguments, 0));
+ text.push('\n');
+ return text.join('');
+ },
+
+ run: function() {
+ var stdin = process.openStdin();
+ var newLineOnExit = true;
+
+ stdin.setEncoding('utf8');
+ process.stdout.write(cli.greeting);
+
+ DNode(function () {
+ this.name = function (f) { f(cli.clientName) };
+
+ this.joined = function (who) {
+ process.stdout.write(cli.info('joined'));
+ };
+
+ this.parted = function (who) {
+ process.stdout.write(cli.info('parted'));
+ };
+
+ this.said = function (who,msg) {
+ process.stdout.write(cli.info(who + ' said: ' + msg));
+ };
+
+ this.refreshNames = function (names) {
+ process.stdout.write(cli.info('refreshNames'));
+ };
+ }).connect(6060, function (remote) {
+ remote.names(function (names) {
+ process.stdout.write( cli.info('users: ' + names.join(' ')) );
+ });
+
+ process.stdout.write(cli.prompt);
+
+ stdin.addListener('data', function (chunk) {
+ if (chunk === '.quit\n') {
+ newLineOnExit = false;
+ process.exit();
+ }
+ remote.chat(chunk);
+ process.stdout.write(chunk);
+ process.stdout.write(cli.prompt);
+ });
+
+ stdin.addListener('end', function () {
+ process.exit();
+ });
+
+ process.addListener('exit', function () {
+ var msg = cli.info('has ended');
+ if (newLineOnExit) msg = '\n' + msg;
+ process.stdout.write(msg);
+ });
+ });
+ }
+
+};
+
+cli.run();
@@ -0,0 +1,74 @@
+#!/usr/bin/env node
+// Simple DNode chat server example.
+// Just as simple as plain socket.io since it's a simple problem.
+
+var DNode = require('dnode');
+var fs = require('fs');
+var http = require('http');
+var sys = require('sys');
+
+// load the files to serve up into memory
+var html = fs.readFileSync(__dirname + '/chat.html');
+var css = fs.readFileSync(__dirname + '/chat.css');
+var js = require('dnode/web').source();
+
+// simple http server to serve pages and for socket.io transport
+var httpServer = http.createServer(function (req,res) {
+ if (req.url == '/dnode.js') {
+ res.writeHead(200, { 'Content-Type' : 'text/javascript' });
+ res.end(js);
+ }
+ else if (req.url == '/chat.css') {
+ res.writeHead(200, { 'Content-Type' : 'text/css' });
+ res.end(css);
+ }
+ else {
+ res.writeHead(200, { 'Content-Type' : 'text/html' });
+ res.end(html);
+ }
+});
+httpServer.listen(6061);
+
+// share the chat server routines with remote clients
+var names = [];
+var transports = [];
+function ChatServer (client, con) {
+ function xbroadcast(cmd, name, msg) {
+ for(var i = 0; i < transports.length; i++) {
+ transports[i].broadcast(cmd, name, msg);
+ }
+ }
+
+ transports.push(con);
+ var name = '?';
+
+ con.addListener('ready', function () {
+ client.name(function (who) {
+ con.broadcast('joined', who);
+ name = who;
+ names.push(name);
+ con.broadcast('refreshNames', names);
+ });
+ });
+
+ con.addListener('disconnect', function () {
+ con.broadcast('parted', name);
+ var i = names.indexOf(name);
+ if (i >= 0) names.splice(i,1);
+ });
+
+ this.chat = function (msg) {
+ xbroadcast('said', name, msg);
+ };
+
+ this.names = function (f) { f(names) };
+}
+
+DNode(ChatServer)
+ .listen(6060)
+ .listen({
+ protocol : 'socket.io',
+ server : httpServer,
+ transports : 'websocket xhr-multipart xhr-polling htmlfile'
+ .split(/\s+/),
+});
@@ -0,0 +1,39 @@
+var DNode = require('dnode');
+var sys = require('sys');
+var fs = require('fs');
+var http = require('http');
+
+// load the html page and the client-side javascript into memory
+var html = fs.readFileSync(__dirname + '/kite-dnode.html');
+var js = require('dnode/web').source();
+
+// simple http server to serve pages and for socket.io transport
+var httpServer = http.createServer(function (req,res) {
+ if (req.url == '/dnode.js') {
+ res.writeHead(200, { 'Content-Type' : 'text/javascript' });
+ res.end(js);
+ }
+ else {
+ res.writeHead(200, { 'Content-Type' : 'text/html' });
+ res.end(html);
+ }
+});
+httpServer.listen(6061);
+
+// share an object with DNode over socket.io on top of the http server
+DNode(function (client) {
+ this.timesTen = function (n,f) { f(n * 10) };
+ this.whoAmI = function (reply) {
+ client.name(function (name) {
+ reply(name
+ .replace(/Mr\.?/,'Mister')
+ .replace(/Ms\.?/,'Miss')
+ .replace(/Mrs\.?/,'Misses')
+ );
+ })
+ };
+}).listen({
+ protocol : 'socket.io',
+ server : httpServer,
+ transports : 'websocket xhr-multipart xhr-polling htmlfile'.split(/\s+/),
+});
Oops, something went wrong.

0 comments on commit 5bdc447

Please sign in to comment.