重复造轮子之基于nodejs的聊天室
首先说明下,这帖子虽然是原创,但是功能网上已经有很多实现的有很多。我只是记录下自己的进步而已
配置nodejs的环境大家可以看看我的另外一篇博文简单完成nodejs的服务创建。
好了,我们先从服务端代码开始,基于nodejs哦。
简单的config.js文件,代码中的解释如果看不懂,可以再次阅读简单完成nodejs的服务创建这篇博文。如果还是不明白,可以留言询问。
//简单队列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 = $("#chat_box");/*实现逻辑:1、出现新数据2、数据进入接收队列3、执行进接收队列的回调(判断送花数据是单例还是包,我把包定义成需要刷屏的数据)4、单例数据,就是不需要刷屏的数据,直接进入单例队列5、包数据,拆分成单例数据进入单例队列6、使用监听器监听单例队列,按照步长输出*///添加新的送花数据进队列后的回调(内部判断,单例送花,还是送花包)var flowersQueueAddCallBack = function () { //从队列获取一个数据 var _item = flowersQueue.get(); //不存在就返回。。。你懂得 if (!_item) return; //如果数据中的某个属性值确定是需要刷屏处理的,我这边是因为我定的业务逻辑所以这么写了 if (_item.flowersQuantity == 20) { //进入包队列,并执行回调 boxMsgQueue.add(_item, function () { boxMsgQueueAddCallBack(); }); } else { /* 这边也有业务逻辑,就是发普通聊天信息和送花信息,这些不纠结,这边就是直接进入单例队列 事实上我这边这么处理会因为网速,机器好坏,导致聊天,和刷屏一起的时候 没法所有用户同步。 这边其实可以,直接对容器append,单例数据直接获取到,直接插入,我这边暂时没这么修改,下个版本我考虑把它优化掉 */ if (_item.flowersQuantity != 0) { userData[_item.userName] = (userData[_item.userName] || 0) + (_item.flowersQuantity - 0); singletonMsgQueue.add('<p>' + _item.userName + '赠送' + _item.flowersQuantity + '朵鲜花,共' + userData[_item.userName] + '朵</p>'); } else { singletonMsgQueue.add('<p>' + _item.userName + ":" + _item.text + '</p>'); } }};//添加新的包数据进,包数据队列后的回调(出现新的包数据,根据步长,拆分成单例数据进入单例队列)var boxMsgQueueAddCallBack = function () { //取值,同上面的方法 var _item = boxMsgQueue.get(); var i, _setInterval; if (!_item) return //按照步长插入单例队列 i = 0; _setInterval = setInterval(function () { i++; userData[_item.userName] = (userData[_item.userName] || 0) + 1; singletonMsgQueue.add('<p>' + _item.userName + '赠送一朵鲜花,共' + userData[_item.userName] + '朵</p>'); if (i == _item.flowersQuantity) { clearInterval(_setInterval); } }, 200);};//监听单例队列,插入文字(不管是单例数据还是包数据,经过处理都进入单例队列)var monitorSingletonMsgQueue = function () { //获取队列中的第一个 var _item = singletonMsgQueue.get(); var i; //队列存在数据 if (_item) { //插入一条新数据 $chat_box.append(_item).scrollTop(10000); ($chat_box.find("p").length > 200) && ($chat_box.find("p:eq(0)").remove()); //队列数据过多,则加快显示速度 if (singletonMsgQueue.list.length > 100) { i = singletonMsgQueue.list.length; while (i--) { $chat_box.append(singletonMsgQueue.get()).scrollTop(10000); ($chat_box.find("p").length > 200) && ($chat_box.find("p:eq(0)").remove()); } } } }//监听器setInterval(function () { monitorSingletonMsgQueue();}, 200);//获取推送信息var socket = io.connect('http://10.0.252.124:9999');//这边就是获取推送信息的递归了,只要把推送来的数据放到,队列里面就可以了socket.on('chat_box', function (data) { flowersQueue.add(data, function () { flowersQueueAddCallBack(); });});也可以直接留言,有更优的解决方案,最好还是留言吧。大家一起看看