当前位置:编程学习 > JS >>

重复造轮子之基于nodejs的聊天室

首先说明下,这帖子虽然是原创,但是功能网上已经有很多实现的有很多。我只是记录下自己的进步而已
配置nodejs的环境大家可以看看我的另外一篇博文简单完成nodejs的服务创建。
好了,我们先从服务端代码开始,基于nodejs哦。
简单的config.js文件,代码中的解释如果看不懂,可以再次阅读简单完成nodejs的服务创建这篇博文。如果还是不明白,可以留言询问。
[javascript]  
var express = require('express')  
    , routesConfig = require('./routes/config')  
    , http = require('http')  
    , routes = require('./routes/config')  
;  
  
var app = express(),  
    //端口号  
    port = 8888;  
  
app.configure(function () {  
    //定义一个私有变量减少作用域链的检索消耗(其实没必要这么写,1亿次检索才会有性能差异)  
    var _app = app, _express = express  
    //设置视图文件  
    _app.set('views', __dirname + '/views');  
    //设置模板引擎  
    _app.set('view engine', 'ejs');  
    //静态资源管理  
    _app.use(express.static(__dirname + '/'));  
    app.use(express.favicon());  
    //(这个自动处理是将post携带的数据,放到request.body里面)  
    _app.use(_express.bodyParser());  
    //使用请求头数据自动处理:  
    //(这个自动处理是将,某些不是请求头数据在head中或者直接携带在postData中的请求头信息写入到request.method,如果信息在postData里面,会将post.body里面的请求头信息删除)  
    _app.use(_express.methodOverride());  
    //使用调试?  
    //这个不是很清楚看接口对应代码貌似和debug有关  
    _app.use(_app.router);   
});  
app.get('/', routesConfig.default);  
//接受消息  
var chat = require("./routes/chat_box/push");  
app.get('/push', chat.push);  
//异常处理  
app.configure('development', function () {  
    app.use(express.errorHandler());  
});  
//创建这个服务,并指定端口,完了之后初始端口号  
http.createServer(app).listen(port, function () {  
      
    console.log("Express server listening on port " + port);  
});  
在这段代码中,默认访问比如:http://xxxx.xxxx.xxx/  这种类型的自动执行了routesConfig.default,这个我就不细说了,反正就输出个html而已。
然后我们看看消息推送的代码
[javascript]  
//url模块(nodejs)  
var urllib = require('url');  
/*socket模块(nodejs) 
开启推送端口端口号为:9999,这个端口号其实随意的,只要木有被占用就行 
*/  
var io = require('socket.io').listen(9999);  
//简单队列  
var queue = function () {  
    var self = this;  
    this.list = [];  
    this.add = function (data, cb) {  
        self.list.push(data);  
        cb && cb();  
    };  
    this.get = function () {  
        return self.list.shift();  
    };  
};  
//事实上这个user是个山寨的数据库(我用来缓存数据的,这里偷懒了)  
var user = {};  
/* 
事件绑定 
connection事件为,服务端出现链接后执行 
我在该事件中表现为,每存在一个链接用户,就为其开出一片内存,用于存放推送信息,这里我没优化,用户多的情况下 应该很坑爹 
然后执行推送数据的监听 
*/  
io.sockets.on('connection', function (socket) {  
    (!user[socket.id]) && (user[socket.id] = new queue());  
    _push(socket);  
});  
/* 
开启推送数据的监听,用setInterval,伪造出多线程 
这边我没什么好的想法,有好的解决方案,求交流 
*/  
var _push = function (socket) {  
    var _setInterval;  
    _setInterval = setInterval(function () {  
        var item = user[socket.id] && user[socket.id].get();  
        if (item) {  
            socket.emit("chat_box", item);  
        }  
    }, 100);  
};  
/* 
接受发送消息的接口,记得那个配置的js吗? 
var chat = require("./routes/chat_box/push"); 
app.get('/push', chat.push); 
这句话就是转到这个接口来处理了 
*/  
exports.push = function (req, res) {  
    var params  
    , uname  
    , quantity  
    , text;  
    params = urllib.parse(req.url, true).query;  
    uname = params.uname;  
    quantity = params.quantity;  
    text = params.text;  
    //接受到发送消息后,为每个链接用户加入推送消息     
    for (var i in user) {  
        user[i].add({  
            userName: uname,  
            flowersQuantity: quantity,  
            text: text  
        })  
    }  
    //服务端的监控,可以在命令提示符中看到  
    console.log('有新消息');  
};  
好了服务端的代码就这些了,这里主要还是依靠socket.io这个nodejs插件。
接下来,我们看下客户端的脚本,需要说明的是因为刚开始写的时候需求不同,个别命名还是初期的命名,从英文角度看,有点变扭。
[javascript] 
//简单队列  
var queue = function () {  
    var self = this;  
    this.list = [];  
    this.add = function (data, cb) {  
        self.list.push(data);  
        cb && cb();  
    };  
    this.get = function () {  
        return self.list.shift();  
    };  
}  
//接收队列  
var flowersQueue = new queue()  
//单例队列  
, singletonMsgQueue = new queue()  
//包队列  
, boxMsgQueue = new queue()  
//用户送花总数存住对象  
, userData = {}  
, $chat_box = $(
补充:web前端 , JavaScript ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,