Przeglądaj źródła

Merge branch 'master' of https://github.com/Omnimaga/OmnomIRC3

Florian DORMONT 11 lat temu
rodzic
commit
b2b7d5ba5d
1 zmienionych plików z 210 dodań i 174 usunięć
  1. 210 174
      app/OmnomIRC.js

+ 210 - 174
app/OmnomIRC.js

@@ -3,202 +3,238 @@ var fs = require('fs'),
 	url = require('url'),
 	path = require('path'),
 	vm = require('vm'),
-	mimeTypes = {
-		'html': 'text/html',
-		'js': 'text/javascript',
-		'css': 'text/css',
-		'png': 'image/png',
-		'jpg': 'image/jpeg'
-	},
-	app = require('http').createServer(function(req,res){
-		req.addListener('end',function(){
-			logger.debug('served static content for '+req.url);
-			var uri = url.parse(req.url).pathname,
-				serveFile = function(filename,req,res){
-					try{
-						stats = fs.lstatSync(filename);
-					}catch(e){
-						res.writeHead(404,{
-							'Content-type': 'text/plain'
-						});
-						res.write('404 Not Found\n');
-						res.end();
-						return;
-					}
-					if(stats.isFile()){
-						var fileStream,
-							mimetype = mimeTypes[path.extname(filename).split('.')[1]];
-						res.writeHead(200,{
-							'Content-Type': mimetype
-						});
-						fileStream = fs.createReadStream(filename);
-						fileStream.pipe(res);
-					}else if(stats.isDirectory()){
-						if(fs.existsSync(path.join(filename,'index.html'))){
-							serveFile(path.join(filename,'index.html'),req,res);
-						}else if(fs.existsSync(path.join(filename,'index.htm'))){
-							serveFile(path.join(filename,'index.htm'),req,res);
-						}else if(fs.existsSync(path.join(filename,'index.txt'))){
-							serveFile(path.join(filename,'index.txt'),req,res);
-						}else{
+	toobusy = function(){return false;},//require('toobusy'),
+	cluster = require('cluster');
+if(cluster.isMaster){
+	for(var i=0;i<require('os').cpus().length;i++){
+		cluster.fork();
+	}
+	cluster.on('exit', function(worker, code, signal) {
+		console.log('worker ' + worker.process.pid + ' died');
+	});
+}else{
+	var RedisStore = require('socket.io/lib/stores/redis'),
+		redis  = require('socket.io/node_modules/redis'),
+		pub    = redis.createClient(),
+		sub    = redis.createClient(),
+		client = redis.createClient(),
+		mimeTypes = {
+			'html': 'text/html',
+			'js': 'text/javascript',
+			'css': 'text/css',
+			'png': 'image/png',
+			'jpg': 'image/jpeg'
+		},
+		app = require('http').createServer(function(req,res){
+			if(toobusy()){
+				res.writeHead(503,{
+					'Content-type': 'text/plain'
+				});
+				res.write('503 Server busy.\n');
+				res.end();
+				return;
+			}
+			req.addListener('end',function(){
+				logger.debug('served static content for '+req.url);
+				var uri = url.parse(req.url).pathname,
+					serveFile = function(filename,req,res){
+						try{
+							stats = fs.lstatSync(filename);
+						}catch(e){
+							res.writeHead(404,{
+								'Content-type': 'text/plain'
+							});
+							res.write('404 Not Found.\n');
+							res.end();
+							return;
+						}
+						if(stats.isFile()){
+							var fileStream,
+								mimetype = mimeTypes[path.extname(filename).split('.')[1]];
 							res.writeHead(200,{
+								'Content-Type': mimetype
+							});
+							fileStream = fs.createReadStream(filename);
+							fileStream.pipe(res);
+						}else if(stats.isDirectory()){
+							if(fs.existsSync(path.join(filename,'index.html'))){
+								serveFile(path.join(filename,'index.html'),req,res);
+							}else if(fs.existsSync(path.join(filename,'index.htm'))){
+								serveFile(path.join(filename,'index.htm'),req,res);
+							}else if(fs.existsSync(path.join(filename,'index.txt'))){
+								serveFile(path.join(filename,'index.txt'),req,res);
+							}else{
+								res.writeHead(200,{
+									'Content-Type': 'text/plain'
+								});
+								res.write('Index of '+url+'\n');
+								res.write('TODO, show index');
+								res.end();
+							}
+						}else{
+							res.writeHead(500,{
 								'Content-Type': 'text/plain'
 							});
-							res.write('Index of '+url+'\n');
-							res.write('TODO, show index');
+							res.write('500 Internal server error\n');
 							res.end();
 						}
+					},
+					filepath = unescape(uri);
+				if(filepath.substr(0,5) == '/api/'){
+					filepath = path.join('./api/',filepath.substr(5));
+					logger.debug('Attempting to run api script '+filepath);
+					if(fs.existsSync(filepath)){
+						fs.readFile(filepath,function(e,data){
+							if(e){
+								logger.error(e);
+								res.end('null;');
+							}else{
+								var output = '',
+									sandbox = {
+										log: function(text){
+											output += text;
+										},
+										error: function(msg){
+											logger.error(msg);
+										},
+										info: function(msg){
+											logger.info(msg);
+										},
+										debug: function(msg){
+											logger.debug(msg);
+										},
+										head: {
+											'Content-Type': 'text/javascript'
+										},
+										returnCode: 200,
+										vm: vm,
+										fs: fs
+									};
+								vm.runInNewContext(data,sandbox,filepath);
+								res.writeHead(sandbox.returnCode,sandbox.head);
+								res.end(output);
+							}
+						});
 					}else{
-						res.writeHead(500,{
-							'Content-Type': 'text/plain'
+						res.writeHead(404,{
+							'Content-Type': 'text/javascript'
 						});
-						res.write('500 Internal server error\n');
-						res.end();
+						res.end('null;');
 					}
-				},
-				filepath = unescape(uri);
-			if(filepath.substr(0,5) == '/api/'){
-				filepath = path.join('./api/',filepath.substr(5));
-				logger.debug('Attempting to run api script '+filepath);
-				if(fs.existsSync(filepath)){
-					fs.readFile(filepath,function(e,data){
-						if(e){
-							logger.error(e);
-							res.end('null;');
-						}else{
-							var output = '',
-								sandbox = {
-									log: function(text){
-										output += text;
-									},
-									error: function(msg){
-										logger.error(msg);
-									},
-									info: function(msg){
-										logger.info(msg);
-									},
-									debug: function(msg){
-										logger.debug(msg);
-									},
-									head: {
-										'Content-Type': 'text/javascript'
-									},
-									returnCode: 200,
-									vm: vm,
-									fs: fs
-								};
-							vm.runInNewContext(data,sandbox,filepath);
-							res.writeHead(sandbox.returnCode,sandbox.head);
-							res.end(output);
-						}
-					});
 				}else{
-					res.writeHead(404,{
-						'Content-Type': 'text/javascript'
-					});
-					res.end('null;');
+					serveFile(path.join('./www/',filepath),req,res);
 				}
-			}else{
-				serveFile(path.join('./www/',filepath),req,res);
-			}
-		}).resume();
-	}).listen(80),
-	io = require('socket.io').listen(app)
-	logger = io.log;
-io.set('log level',3);
-io.sockets.on('connection',function(socket){
-	socket.on('join',function(data){
-		socket.join(data.name);
-		data.title = data.name;
-		socket.emit('join',{
-			name: data.name,
-			title: data.title
-		});
-		sendUserList(data.name);
-		socket.get('nick',function(e,nick){
-			logger.debug(nick+' joined '+data.name);
-			io.sockets.in(data.name).emit('message',{
-				message: nick+' joined the channel',
-				room: data.name,
-				from: 0
+			}).resume();
+		}).listen(80),
+		io = require('socket.io').listen(app)
+		logger = io.log;
+	io.set('log level',3);
+	io.set('store', new RedisStore({
+		redisPub : pub,
+		redisSub : sub,
+		redisClient : client
+	}));
+	io.sockets.on('connection',function(socket){
+		socket.on('join',function(data){
+			socket.join(data.name);
+			data.title = data.name;
+			socket.emit('join',{
+				name: data.name,
+				title: data.title
 			});
-		});
-	});
-	socket.on('part',function(data){
-		socket.leave(data.name);
-		socket.get('nick',function(e,nick){
-			logger.debug(nick+' left '+data.name);
 			sendUserList(data.name);
+			socket.get('nick',function(e,nick){
+				logger.debug(nick+' joined '+data.name);
+				io.sockets.in(data.name).emit('message',{
+					message: nick+' joined the channel',
+					room: data.name,
+					from: 0
+				});
+			});
 		});
-	});
-	socket.on('disconnect',function(data){
-		var rooms = io.sockets.manager.rooms,
-			i,
-			room;
-		for(i in rooms){
-			if(rooms[i] != '' && typeof rooms[i] == 'string'){
-				try{
-					room = rooms[i].substr(1);
-				}catch(e){}
-				sendUserList(names);
+		socket.on('part',function(data){
+			socket.leave(data.name);
+			socket.get('nick',function(e,nick){
+				logger.debug(nick+' left '+data.name);
+				sendUserList(data.name);
+			});
+		});
+		socket.on('disconnect',function(data){
+			var rooms = io.sockets.manager.rooms,
+				i,
+				room;
+			for(i in rooms){
+				if(rooms[i] != '' && typeof rooms[i] == 'string'){
+					try{
+						room = rooms[i].substr(1);
+					}catch(e){}
+					sendUserList(room);
+				}
 			}
-		}
-	});
-	socket.on('message',function(data){
-		logger.debug('message sent to '+data.room);
-		io.sockets.in(data.room).emit('message',data);
-	});
-	socket.on('echo',function(data){
-		logger.debug('echoing to '+data.room);
-		socket.emit('message',data);
-	});
-	socket.on('names',function(data){
-		var sockets = io.sockets.clients(data.name),
-			i;
-		socket.emit('message',{
-			message: data.name+' users:',
-			room: data.name,
-			from: 0
 		});
-		for(i in sockets){
-			sockets[i].get('nick',function(e,nick){
+		socket.on('message',function(data){
+			logger.debug('message sent to '+data.room);
+			io.sockets.in(data.room).emit('message',data);
+		});
+		socket.on('echo',function(data){
+			logger.debug('echoing to '+data.room);
+			socket.emit('message',data);
+		});
+		socket.on('names',function(data){
+			var sockets = io.sockets.clients(data.name),
+				i;
+			runWithUserList(data.name,function(users){
 				socket.emit('message',{
-					message: '	'+nick,
+					message: data.name+" users:\n"+users.join("\n\t"),
 					room: data.name,
 					from: 0
 				});
+				sendUserList(data.name);
 			});
-		}
-		sendUserList(data.name);
-	});
-	socket.on('auth',function(data){
-		logger.info(data.nick+' registered');
-		// TODO - authorize
-		socket.set('nick',data.nick.substr(0,12));
-		socket.emit('authorized',{
-			nick: data.nick.substr(0,12)
 		});
+		socket.on('auth',function(data){
+			logger.info(data.nick+' registered');
+			// TODO - authorize
+			socket.set('nick',data.nick.substr(0,12));
+			socket.emit('authorized',{
+				nick: data.nick.substr(0,12)
+			});
+		});
+		var runWithUserList = function(room,callback){
+				var sockets = io.sockets.clients(room),
+					i = 0,
+					ret = [],
+					getNext = function(){
+						if(i < sockets.length){
+							sockets[i].get('nick',function(e,nick){
+								if(e){
+									logger.error(e);
+									ret.push('');
+								}else{
+									logger.debug(room+' '+nick);
+									ret.push(nick);
+								}
+								i++;
+								getNext();
+							});
+						}else{
+							callback(ret);
+						}
+					};
+				getNext();
+			},
+			sendUserList = function(room){
+				if(typeof room != 'undefined'){
+					runWithUserList(room,function(users){
+						io.sockets.in(room).emit('names',{
+							room: room,
+							names: users
+						});
+					});
+				}
+			};
 	});
-	var usersInRoom = function(room){
-			var sockets = io.sockets.clients(room),
-				i,
-				ret = [];
-			for(i in sockets){
-				sockets[i].get('nick',function(e,nick){
-					ret.push(nick);
-				});
-			}
-			return ret;
-		},
-		sendUserList = function(room){
-			if(typeof room != 'undefined'){
-				io.sockets.in(room).emit('names',{
-					room: room,
-					names: usersInRoom(room)
-				});
-			}
-		};
-});
+}
 process.on('uncaughtException',function(e){
 	logger.error(e);
 });