Anyway, at this level, I maintain two modules. The first, the Node.js entry point, starts the server with callbacks defined in the main module. To be precise, the first file is not actually a module as we've defined modules so far. Rather, it's a simple script calling the appropriate bootstrapping methods:
(server.js)
var net = require('net');
var main = require('./main').main;
net.createServer(main.connection_listener)
.listen(1337, "127.0.0.1", main.event_listener);
That's it! Pretty cool. This just spawns a server on port 1337 using listeners defined in main, where the bulk of the communication implementation resides:
(main.js)
var version = require('./version').version;
var date = require('./date').date;
var random = require('./random').random;
exports.main = function() {
// This is a private class object used to build
// the response generator needed based on the
// type of request. The dispatch(.) method takes
// a string and then calls the corresponding
// factory method based on the predefined module
// interfaces (see the previous two posts for
// more information on those interface
// definitions). If someone requests an
// operation we don't recognize, we create an
// anonymous class object implementing
// the generator interface.
var _processor = function() {
var SCALE = 10;
var DATE = 1;
var RANDOM = 2;
var UNKNOWN = 3;
var parser = function(cmd) {
if (cmd.match(/date/ig)) return DATE;
if (cmd.match(/random/ig)) return RANDOM;
return UNKNOWN;
}
this.dispatch = function(cmd) {
var generator;
switch(parser(cmd.toString())) {
case DATE:
generator = new date.Generator();
break;
case RANDOM:
generator = new random.Generator(SCALE);
break;
default:
generator = new function() {
this.generate = function() {
return 'undefined token submitted.';
}
}
}
return generator.generate();
}
}
// This is a private function building a version
// string using information defined in the version
// module.
var _build_version_string = function() {
return version_string = version.major + '.'
+ version.minor + '.'
+ version.patch + ' - '
+ version.status;
}
// The server entry point. We write output to the
// requestor socket as well as debug information
// to the console, first. We then define a handler
// for submitted data using our private processor
// class. The handler processes the request
// and emits a bit more status information to the
// console. Finally, we drop binding status to the
// console and return.
var _entry_pt = function(socket) {
socket.write('date & random server: '
+ _build_version_string()
+ '; enter command\r\n',
'ascii',
function() {
console.log('...welcome sent to '
+ socket.remotePort
+ '@'
+ socket.remoteAddress);
});
var processor = new _processor();
socket.on('data', function(data) {
console.log('data received: "' + data + '"');
var retval = processor.dispatch(data);
console.log('response: ' + retval);
socket.write(retval + '\r\n');
});
}
var _event_listener = function() {
console.log('...server has been bound.');
}
// The module signature implementation.
return {
connection_listener: _entry_pt,
event_listener: _event_listener
}
}();
Note the comments above describing what's what in the implementation module.
Now, to run this on the command line type:
$ node lib/server.js
This'll bootstrap the server and kick it off, sending confirmation messages to the console. To connect, use telnet:
$ telnet localhost 1337
And you'll be greeted by the smarmy welcome screen:
Connected to localhost.
Escape character is '^]'.
date & random server: 1.0.0 - gold; enter command
No comments:
Post a Comment