`

我也来学习nodejs 没有就自己来 色色实现迷你 MVC

阅读更多

我也来学习nodejs 郁闷的天 文档很不咋的 实例根本跟不上 产品不成熟

 

完事开头难,聊天室还是有困难的啊 写起来 今天下午第一次接触这个玩意 ...

 

忽然发现 完全与之前的web开发 不挂钩 后端 还得自己去 处理各种请求 ....

 

实现聊天室 如果没有一个标准的话 后面东西很乱.... 写就写好 ...

 

先把框架雏形写出来再说 ... 靠 我也实现个MVC出来玩

 

下面这个雏形 基本源自 我自己的php框架思想 .... 基本有了 明天继续实现

 

今明2天把 框架实现好,后面可以自己叠加应用了 .......

 

可能哥以后 就有段时间折腾这破玩意了...

 

 

 

console.log('kenxu聊天室程序');
// 实现 简易的MVC模式
var Http = require('http');
var System = require("sys");
var FileSystem = require("fs");
var Url = require("url");

// 工具代码
var __undef = 'undefined',__proto = "prototype";
Object.extend = function(dest, source) {
	for (var property in source) dest[property] = source[property];
	return dest;
};
Object.extend(String[__proto],{
	trim: function(){return this.replace(/^\s+|\s+$/g, '');}
});
var Utilities = {
	arrayMap: function(list, fn) {
		if (list && list.length){
			var r = [];
			for (var i = 0; i < list.length; i++) {
				var x = fn(list[i], i);
				if (x !== null) {
					r.push(x) ;
				}
			}
			return r ;
		}
		return [];
	} ,
	each: function(list,fn){
		if (list && list.length)
			for (var i = 0; i < list.length; i++)
				if (fn.call(list[i],i) == '#end#') break ;
	}
};


/**
 * UDI 对象 实现请求资源定位器
 * @type 
 */
var UDI = {
	UDI_CONTROLLER: 'controller',
	UDI_ACTION: 'action',
	DEFAULT_CONTROLLER: 'application', 
	DEFAULT_ACTION: 'index' 
};

function __request_filter(pathinfo){
	var pathinfo = pathinfo || '/';
	var parts = pathinfo.substr(1).split('/');
	
	var params = {};
	if (parts[0] && parts[0].trim().length > 0){
		params[UDI.UDI_CONTROLLER] = parts[0].trim();
	}
	if (parts[1] && parts[1].trim().length > 0){
		params[UDI.UDI_ACTION] = parts[1].trim();
	}
	
    for (var i = 2; i < parts.length; i += 2) {
        if (parts[i + 1]) {
            params[parts[i]] = parts[i + 1];
        }
    }
    
    // 校验 UDI参数是否存在
    if (!params[UDI.UDI_CONTROLLER]){
    	params[UDI.UDI_CONTROLLER] = UDI.DEFAULT_CONTROLLER;
    }
    if (!params[UDI.UDI_ACTION]){
    	params[UDI.UDI_ACTION] = UDI.DEFAULT_ACTION;
    }
    
	return params;
}

var QRequest = function(req){
	this._req = req;
	
};

/**
 * 单一入口分发器
 * @type 
 */
var Dispatcher = {
	
	/**
	 * 请求分发方法,可能会抛出异常,不知道异常怎么写...
	 * 
	 * @param {} request
	 * @param {} response
	 */
	dispose: function(request, response){
		
		// 取拼装控制器以及action
		var pathinfo = Url.parse(request.url).pathname;
		
		var params = __request_filter(pathinfo);
		console.log(params);
		
		response.writeHead(200, {'Content-Type': 'text/plain'});
		response.end(pathinfo + '\n');
		
	}
	
};

//SFW.Controller = function(request)

Http.createServer(function (request, response) {
	try {
		Dispatcher.dispose(request, response);
	} 
	catch(e){
		console.log(e);
	}
}).listen(8124);

 

 

运行之后

 

http://localhost:8124/ 会输出 { controller: 'application', action: 'index' }

 

http://localhost:8124/hello/world/id/123/page/12 会输出

{ controller: 'hello',
  action: 'world',
  id: '123',
  page: '12' }

 

似乎 还行啊 不知道性能怎么样....

 

下面把 网站贴下 方便 学习:

 

 

https://github.com/joyent/node/wiki/modules

http://cnodejs.org/blog/?p=104

http://www.cnblogs.com/QLeelulu/archive/2011/01/28/nodejs_into_and_n2mvc.html  源代码下载

http://cnodejs.org/cman/ []

http://cnodejs.org/api/

http://seajs.com/

http://www.w3school.com.cn/js/jsref_substr.asp

 

  • learnNode.zip (43.3 KB)
  • 描述: 另一个简单的MVC雏形,可以学习
  • 下载次数: 23
3
5
分享到:
评论
9 楼 vb2005xu 2011-06-01  
最后一个评论 结贴了 ... 基本雏形完成 后面的代码不再贴出来...

支持 查找指定的 action 并执行,支持 action里面 转发请求...

console.log('kenxu聊天室程序');

/*
 * 编码规范:
 * 模块引用,类定义 均使用驼峰风格定义
 * 
 */

// 实现 简易的MVC模式
var Http = require('http');
var System = require("sys");
var FileSystem = require("fs");
var Url = require("url");

// 工具代码
var __undef = 'undefined',__proto = "prototype";
Object.extend = function(dest, source) {
	for (var property in source) dest[property] = source[property];
	return dest;
};
Object.extend(String[__proto],{
	trim: function(){return this.replace(/^\s+|\s+$/g, '');}
});

var Utilities = {
	arrayMap: function(list, fn) {
		if (list && list.length){
			var r = [];
			for (var i = 0; i < list.length; i++) {
				var x = fn(list[i], i);
				if (x !== null) {
					r.push(x) ;
				}
			}
			return r ;
		}
		return [];
	} ,
	each: function(list,fn){
		if (list && list.length)
			for (var i = 0; i < list.length; i++)
				if (fn.call(list[i],i) == '#end#') break ;
	}
};


/**
 * UDI 对象 实现请求资源定位器
 * @type 
 */
var UDI = {
	
	UDI_MODULE: 'module',
	UDI_CONTROLLER: 'controller',
	UDI_ACTION: 'action',
	DEFAULT_MODULE: 'default', 
	DEFAULT_CONTROLLER: 'application', 
	DEFAULT_ACTION: 'index' ,
	
	normalize: function(module,controller,action){
		var udi = {};
		udi[UDI.UDI_MODULE] = module || UDI.DEFAULT_MODULE;
		udi[UDI.UDI_CONTROLLER] = controller || UDI.DEFAULT_CONTROLLER;
		udi[UDI.UDI_ACTION] = action || UDI.DEFAULT_ACTION;
		
		return udi;
	},
	
	format: function(udi){
		var udi = udi || {};
		if (!udi[UDI.UDI_MODULE]){
	    	udi[UDI.UDI_MODULE] = UDI.DEFAULT_MODULE;
	    }
	    if (!udi[UDI.UDI_CONTROLLER]){
	    	udi[UDI.UDI_CONTROLLER] = UDI.DEFAULT_CONTROLLER;
	    }
	    if (!udi[UDI.UDI_ACTION]){
	    	udi[UDI.UDI_ACTION] = UDI.DEFAULT_ACTION;
	    }		
		return udi;
	},
	
	dumpString: function(udi){
		return udi[UDI.UDI_CONTROLLER] + '/' + udi[UDI.UDI_ACTION] + '@' + udi[UDI.UDI_MODULE];
	}
};

function __pathinfo_filter(pathinfo){
	var pathinfo = pathinfo || '/';
	var parts = pathinfo.substr(1).split('/');
	
	var params = {};
	if (parts[0] && parts[0].trim().length > 0){
		params[UDI.UDI_CONTROLLER] = parts[0].trim();
	}
	if (parts[1] && parts[1].trim().length > 0){
		params[UDI.UDI_ACTION] = parts[1].trim();
	}
	
    for (var i = 2; i < parts.length; i += 2) {
        if (parts[i + 1]) {
            params[parts[i]] = parts[i + 1];
        }
    }
    
    // 校验 UDI参数是否存在
	return UDI.format(params);
}

/**
 * 单一入口分发器
 * @type 
 */
function Dispatcher(request, response){
	
	this.request = request;
	this.response = response;
	this.params = null;
	this.requestUDI = null;
	
	this.parsePathinfo = function(pathinfo){
		return __pathinfo_filter(pathinfo);
	};
	
	this.params = this.parsePathinfo(Url.parse(request.url).pathname);
	
	/**
	 * 设置请求资源对象
	 * @param {} udi
	 */
	this.setRequestUDI = function(udi){
		// 调用此方法之前必须 手动对 参数udi 做 format操作
		for(var p in udi){
			if (udi.hasOwnProperty(p))
				this.params[p] = udi[p];
		}		
		this.requestUDI = udi;
	};
	
	this.setRequestUDI(this.params);
	
	/**
	 * 请求分发
	 * @param {} udi
	 */
	this.dispose = function(udi){
		if (udi) this.setRequestUDI(udi);
		console.log(this.params);
				
		// 加载控制器类
		var sc = this.loadController(this.requestUDI);
		if (!sc){
			response.writeHead(404, {'Content-Type': 'text/plain'});			
			var msg = '控制器不存在: udi=' + UDI.dumpString(this.requestUDI);			
			response.end(msg + '\n');
			return;
		}
		
		if (!sc.existsAction(this.requestUDI[UDI.UDI_ACTION])){
			response.writeHead(404, {'Content-Type': 'text/plain'});
			var msg = 'Action不存在: udi=' + UDI.dumpString(this.requestUDI);
			response.end(msg + '\n')
			return;
		}
		
		var resonse = sc.execute(this.requestUDI[UDI.UDI_ACTION]);
		
		return resonse;
	};
	
	/**
	 * 加载控制器
	 * @param {} udi
	 * 
	 * @return Controller
	 */
	this.loadController = function(udi){
				
		do {			
			var module = udi[UDI.UDI_MODULE];
			if (! (App.controllerPackage[module]) )
				break;
			
			var controller = udi[UDI.UDI_CONTROLLER];
			if (! (App.controllerPackage[module][controller]) )
				break;
			
			return new App.controllerPackage[module][controller](this);
				
		} while(false);
		return null;
	};
}

/**
 * 控制器类
 * @param Dispatcher dispatcher
 */
function Controller(){
	
	this.isGet = function(){
		return this.dispatcher.request.method === 'GET';
	};
	this.isPost = function(){
		return this.dispatcher.request.method === 'POST';
	};
	this.isHead = function(){
		return this.dispatcher.request.method === 'HEAD';
	};
	
	/**
	 * action 是否存在
	 * 
	 * @param string action
	 * @return boolean
	 */
	this.existsAction = function(action){
		var met = action + 'Action';
		return this[met] && typeof this[met] == 'function';
	};
	
	/**
	 * 执行action
	 * @param string action
	 * 
	 * @return mixed
	 */
	this.execute = function(action){
		var met = action + 'Action';
		return this[met]();
	};
	
	/**
	 * 将请求转发到 指定 的UDI
	 * 
	 * @param string module
	 * @param string controller
	 * @param string action
	 * 
	 * @return mixed
	 */
	this.forward = function(module,controller,action)
    {
    	return this.dispatcher.dispose(UDI.normalize(module,controller,action));
    }
} 

var App = {
	controllerPackage: {}
};

// 定义缺省模块里面的控制器
App.controllerPackage[UDI.DEFAULT_MODULE] = {};
// 定义默认控制器模块的快捷引用
var __scp_default = App.controllerPackage[UDI.DEFAULT_MODULE];

__scp_default.application = function(dispatcher){
	this.dispatcher = dispatcher;
	
	this.indexAction = function(){
		return this.forward('default','hello','index');
	};
};
__scp_default.application.prototype = new Controller();

__scp_default.hello = function(dispatcher){
	this.dispatcher = dispatcher;
	
	this.indexAction = function(){
		return '找到B';
	};
};
__scp_default.hello.prototype = new Controller();


Http.createServer(function (request, response) {
//	try {
		//设置2个处理器: 1. 处理静态资源文件; 2. 处理动态请求的资源		
		
		var wd = new Dispatcher(request, response);
		var rst = wd.dispose();
		if (rst){
			response.writeHead(200, {'Content-Type': 'text/plain'});
			response.end(rst + '\n');
		}
		// 每次必须调用 不然客户端似乎会傻傻的等 ... 暂不理解为什么
		response.end();
//	} 
//	catch(e){
//		console.log(e);
//	}
}).listen(8124);
8 楼 vb2005xu 2011-06-01  
完整的新版本 有个雏形了 ...

console.log('kenxu聊天室程序');

/*
 * 编码规范:
 * 模块引用,类定义 均使用驼峰风格定义
 * 
 * 
 */

// 实现 简易的MVC模式
var Http = require('http');
var System = require("sys");
var FileSystem = require("fs");
var Url = require("url");

// 工具代码
var __undef = 'undefined',__proto = "prototype";
Object.extend = function(dest, source) {
	for (var property in source) dest[property] = source[property];
	return dest;
};
Object.extend(String[__proto],{
	trim: function(){return this.replace(/^\s+|\s+$/g, '');}
});

var Utilities = {
	arrayMap: function(list, fn) {
		if (list && list.length){
			var r = [];
			for (var i = 0; i < list.length; i++) {
				var x = fn(list[i], i);
				if (x !== null) {
					r.push(x) ;
				}
			}
			return r ;
		}
		return [];
	} ,
	each: function(list,fn){
		if (list && list.length)
			for (var i = 0; i < list.length; i++)
				if (fn.call(list[i],i) == '#end#') break ;
	}
};


/**
 * UDI 对象 实现请求资源定位器
 * @type 
 */
var UDI = {
	
	UDI_MODULE: 'module',
	UDI_CONTROLLER: 'controller',
	UDI_ACTION: 'action',
	DEFAULT_MODULE: 'default', 
	DEFAULT_CONTROLLER: 'application', 
	DEFAULT_ACTION: 'index' ,
	
	normalize: function(module,controller,action){
		var udi = {};
		udi[UDI.UDI_MODULE] = module || UDI.DEFAULT_MODULE;
		udi[UDI.UDI_CONTROLLER] = controller || UDI.DEFAULT_CONTROLLER;
		udi[UDI.UDI_ACTION] = action || UDI.DEFAULT_ACTION;
		
		return udi;
	},
	
	format: function(udi){
		var udi = udi || {};
		if (!udi[UDI.UDI_MODULE]){
	    	udi[UDI.UDI_MODULE] = UDI.DEFAULT_MODULE;
	    }
	    if (!udi[UDI.UDI_CONTROLLER]){
	    	udi[UDI.UDI_CONTROLLER] = UDI.DEFAULT_CONTROLLER;
	    }
	    if (!udi[UDI.UDI_ACTION]){
	    	udi[UDI.UDI_ACTION] = UDI.DEFAULT_ACTION;
	    }		
		return udi;
	}
};

function __pathinfo_filter(pathinfo){
	var pathinfo = pathinfo || '/';
	var parts = pathinfo.substr(1).split('/');
	
	var params = {};
	if (parts[0] && parts[0].trim().length > 0){
		params[UDI.UDI_CONTROLLER] = parts[0].trim();
	}
	if (parts[1] && parts[1].trim().length > 0){
		params[UDI.UDI_ACTION] = parts[1].trim();
	}
	
    for (var i = 2; i < parts.length; i += 2) {
        if (parts[i + 1]) {
            params[parts[i]] = parts[i + 1];
        }
    }
    
    // 校验 UDI参数是否存在
	return UDI.format(params);
}

/**
 * 单一入口分发器
 * @type 
 */
function Dispatcher(request, response){
	
	this.request = request;
	this.response = response;
	this.params = null;
	this.requestUDI = null;
	
	this.parsePathinfo = function(pathinfo){
		return __pathinfo_filter(pathinfo);
	};
	
	this.params = this.parsePathinfo(Url.parse(request.url).pathname);
	
	/**
	 * 设置请求资源对象
	 * @param {} udi
	 */
	this.setRequestUDI = function(udi){
		// 调用此方法之前必须 手动对 参数udi 做 format操作
		for(var p in udi){
			if (udi.hasOwnProperty(p))
				this.params[p] = udi[p];
		}		
		this.requestUDI = udi;
	};
	
	this.setRequestUDI(this.params);
	
	/**
	 * 请求分发
	 * @param {} udi
	 */
	this.dispose = function(udi){
		if (udi) this.setRequestUDI(udi);
		console.log(this.params);
				
		// 加载控制器类
		var sc = this.loadController(this.requestUDI);
		if (!sc){
			response.writeHead(404, {'Content-Type': 'text/plain'});
			response.end('资源不存在' + '\n');
			return;
		}
		
//		var msg = this.request.url;
		var msg = sc.name;
		response.writeHead(200, {'Content-Type': 'text/plain'});
		response.end(msg + '\n');
	};
	
	/**
	 * 加载控制器
	 * @param {} udi
	 * 
	 * @return Controller
	 */
	this.loadController = function(udi){
				
		do {			
			var module = udi[UDI.UDI_MODULE];
			if (! (App.controllerPackage[module]) )
				break;
			
			var controller = udi[UDI.UDI_CONTROLLER];
			if (! (App.controllerPackage[module][controller]) )
				break;
			
			return new App.controllerPackage[module][controller](this);
				
		} while(false);
		return null;
	};
}

/**
 * 控制器类
 * @param Dispatcher dispatcher
 */
function Controller(){
	
	this.isGet = function(){
		return this.dispatcher.request.method === 'GET';
	};
	this.isPost = function(){
		return this.dispatcher.request.method === 'POST';
	};
	this.isHead = function(){
		return this.dispatcher.request.method === 'HEAD';
	};
} 

var App = {
	controllerPackage: {}
};

// 定义缺省模块里面的控制器
App.controllerPackage[UDI.DEFAULT_MODULE] = {};
// 定义默认控制器模块的快捷引用
var __scp_default = App.controllerPackage[UDI.DEFAULT_MODULE];

__scp_default.application = function(dispatcher){
	this.dispatcher = dispatcher;
	this.name = '你好';
};
__scp_default.application.prototype = new Controller();

__scp_default.hello = function(dispatcher){
	this.dispatcher = dispatcher;
	this.name = '你好';
};
__scp_default.hello.prototype = new Controller();



//SFW.Controller = function(request)

Http.createServer(function (request, response) {
//	try {
		//设置2个处理器: 1. 处理静态资源文件; 2. 处理动态请求的资源		
		
		( new Dispatcher(request, response) ).dispose();
//	} 
//	catch(e){
//		console.log(e);
//	}
}).listen(8124);


7 楼 vb2005xu 2011-06-01  
加载控制器


/**
 * 单一入口分发器
 * @type 
 */
function Dispatcher(request, response){
	
	this.request = request;
	this.response = response;
	this.params = null;
	this.requestUDI = null;
	
	this.parsePathinfo = function(pathinfo){
		return __pathinfo_filter(pathinfo);
	};
	
	this.params = this.parsePathinfo(Url.parse(request.url).pathname);
	
	/**
	 * 设置请求资源对象
	 * @param {} udi
	 */
	this.setRequestUDI = function(udi){
		// 调用此方法之前必须 手动对 参数udi 做 format操作
		for(var p in udi){
			if (udi.hasOwnProperty(p))
				this.params[p] = udi[p];
		}		
		this.requestUDI = udi;
	};
	
	this.setRequestUDI(this.params);
	
	/**
	 * 请求分发
	 * @param {} udi
	 */
	this.dispose = function(udi){
		if (udi) this.setRequestUDI(udi);
		console.log(this.params);
		
		response.writeHead(200, {'Content-Type': 'text/plain'});
		// 加载控制器类
		var sc = this.loadController(this.requestUDI);
//		var msg = this.request.url;
		var msg = sc.name;
		
		response.end(msg + '\n');
	};
	
	/**
	 * 加载控制器
	 * @param {} udi
	 * 
	 * @return Controller
	 */
	this.loadController = function(udi){
				
		do {			
			var module = udi[UDI.UDI_MODULE];
			if (! (App.controllerPackage[module]) )
				break;
			
			var controller = udi[UDI.UDI_CONTROLLER];
			if (! (App.controllerPackage[module][controller]) )
				break;
			
			return new App.controllerPackage[module][controller](this);
				
		} while(false);
		return null;
	};
}

/**
 * 控制器类
 * @param Dispatcher dispatcher
 */
function Controller(dispatcher){
	
	this.dispatcher = dispatcher;
	
	this.isGet = function(){
		return this.dispatcher.request.method === 'GET';
	};
	this.isPost = function(){
		return this.dispatcher.request.method === 'POST';
	};
	this.isHead = function(){
		return this.dispatcher.request.method === 'HEAD';
	};
} 

var App = {
	controllerPackage: {}
};

// 定义缺省模块里面的控制器
App.controllerPackage[UDI.DEFAULT_MODULE] = {
	
	hello: function(dispatcher){
		this.dispatcher = dispatcher;
		this.name = '你好';
	}
};

//SFW.Controller = function(request)

Http.createServer(function (request, response) {
//	try {
		//设置2个处理器: 1. 处理静态资源文件; 2. 处理动态请求的资源		
		
		( new Dispatcher(request, response) ).dispose();
//	} 
//	catch(e){
//		console.log(e);
//	}
}).listen(8124);

6 楼 vb2005xu 2011-06-01  
function Dispatcher(request, response){
	
	this.request = request;
	this.response = response;
	this.params = null;
	this.requestUDI = null;
	
	this.parsePathinfo = function(pathinfo){
		return __pathinfo_filter(pathinfo);
	};
	
	this.params = this.parsePathinfo(Url.parse(request.url).pathname);
	
	/**
	 * 设置请求资源对象
	 * @param {} udi
	 */
	this.setRequestUDI = function(udi){
		// 调用此方法之前必须 手动对 参数udi 做 format操作
		for(var p in udi){
			if (udi.hasOwnProperty(p))
				this.params[p] = udi[p];
		}		
		this.requestUDI = udi;
	};
	
	this.setRequestUDI(this.params);
	
	/**
	 * 请求分发
	 * @param {} udi
	 */
	this.dispose = function(udi){
		if (udi) this.setRequestUDI(udi);
		console.log(this.params);
		
		// 加载控制器类
		
		response.writeHead(200, {'Content-Type': 'text/plain'});
		response.end(this.request.url + '\n');
	};
}
5 楼 vb2005xu 2011-06-01  
昨天 晚上 我看 cnodejs 翻译的API文档 看到了 2点
大致看完了
看完之后 心凉一大截

...

...

4 楼 vb2005xu 2011-06-01  
再多的工具也是打野战...

我是这样理解的...

拿他与 ruby 来比吧

nodejs 就好比 ruby 这个语言...

但是 rails 应用框架 呢...

nodejs 基本就是最原始的库 ...

再难也要学.... 安心搞一年说不定色色也能成为不错的行手
3 楼 witcheryne 2011-06-01  
npm楼主装了么...

node.js有很多实用工具
Socket.IO, Express

详情看这里:
http://www.infoq.com/cn/articles/nodejs-frameworks
2 楼 vb2005xu 2011-06-01  
个人感觉 功能虽然强大 但是应用开发难度颇大

基本都需要有 强悍的 系统编程以及套接字编程的经验

对于前端熟悉的人除了 js 语法熟悉之外 其它的 仍然没有任何优势可言...

对于PHP程序员 就更难了 很多东西都没有... 都要自己去实现 比如 session cookie $_GET $_POST 这种 常用的东西

这东西 很难 学深 ... 而且似乎各个版本之间 并不怎么兼容

在 应用的层面上 不必任何 服务器端语言简单 ...

不理解国内的那些唱好 nodejs的前端高手 是真的那么牛B 还是 人云亦云...
1 楼 vb2005xu 2011-06-01  
晚上终于把 nodejs-alldoc.rar 给看完了

相关推荐

Global site tag (gtag.js) - Google Analytics