飞嗨,欢迎您的光临,本博所发布之文章皆为作者亲测通过,如有错误,欢迎通过各种方式指正。(本博已于2015.12.6升级到php7,运行环境php7 php-fpm + nginx1.8.0)

node.js聊天室

Node.js/JS lf 2887℃ 0评论

本博之前有过几篇长链接的博文,算了,原生的php socket扩展我放弃了,也用php的swoole扩展实现过websocket聊天室,不过,还是用node.js的socket.io库方便。一开始,尝试不用库,直接写node,不过发现我并没有什么耐心去研究websocket协议,还是用socket.io方便,屏蔽了底层,只关注逻辑。

聊天室地址:http://chat.feehi.com

github地址:http://github.com/liufee/chat

公共聊天

公共聊天

私聊

私聊


私聊

私聊

      写了一段时间的node.js了,真的很有意思,我很喜欢node。不过,我感觉node也有很多不完善的地方,比如说this.key=value,这个key不可以是变量!!!基于对象并非面向对象,好尴尬~~~还有,那个前套n+1层的异步,还是协程好。。。

用了socket.io库之后,整个后端的代码量其实很少,server.js:

var io = require("socket.io")(5000);

var  mongodb = require('mongodb');
var  server  = new mongodb.Server('localhost', 27017, {auto_reconnect:true});
var  db = new mongodb.Db('feehi', server, {safe:true});
var collection;
//连接db
db.open(function(err, db){
    if(err) console.log(err);
    console.log('connect mongodb success');
    // 第1种连接方式
    db.collection('chat',{safe:true}, function(err, collect){
        if(err){
            console.log(err);
        }
        collection = collect;
	});
	
})
//db.createCollection('mycoll', {safe:true}, function(err, collection){})第二种连接

var onlineUsers = {};//在线用户
var onlineCount = 0;//在线用户人数
var userSockets = {};

io.on('connection', function(socket){
	console.log("a user connected");
	socket.on('login', function(data){
		if(!onlineUsers.hasOwnProperty(data.username)){
			socket.name = data.username;
			onlineUsers[data.username] = data;
			userSockets[data.username] = socket;
			onlineCount++;
		}
		collection.find().sort({_id:-1}).limit(15).toArray(function(err,chatList){
			if(err) console.log(err);
       		socket.emit('initChat', {chatList:chatList});
       	}); 
		io.emit('login', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:data});
		console.log(data.username+'加入了聊天室');
	});
	socket.on('message', function(data){
		var dt = new Date();
		var time = (dt.getFullYear())+'-'+(parseInt(dt.getMonth())+1)+'-'+(dt.getDate())+' '+(dt.getHours())+':'+(dt.getMinutes())+':'+(dt.getSeconds());
		data.time = time;
		var dt = {username:data.username,content:data.content,time:data.time};
	 	io.emit('message', dt);
        collection.insert(dt, {safe:true},function(err, result){
            //console.log(result);
        }); 
	 	console.log(dt.username+'说: '+dt.content);
	});
	socket.on('disconnect', function(){
		if(onlineUsers.hasOwnProperty(socket.name)){
			var logoutUser = socket.name;
			console.log(socket.name+'退出了聊天室');
			delete onlineUsers[socket.name];
			delete userSockets[socket.name];
			onlineCount--;
			io.emit('logout', {logoutUser:logoutUser,onlineCount:onlineCount});
		}
	})
	socket.on('privateChat', function(data){
		var dt = new Date();
		var time = (dt.getFullYear())+'-'+(parseInt(dt.getMonth())+1)+'-'+(dt.getDate())+' '+(dt.getHours())+':'+(dt.getMinutes())+':'+(dt.getSeconds());
		data.time = time;
		userSockets[data.toWhom].emit('privateChat', data);
		userSockets[data.username].emit('privateChat', data);
		console.log(data.username+"对"+data.toWhom+"说 "+data.content);
	})
});

      因为之前的nosql一直用的redis,所以,这次保存公共聊天记录用的是mongodb,mongodb果真是流弊闪闪,真的能替代mysql吗,哈哈,mongodb的学习成本还是蛮低的,首先想起标准的sql语句该怎么写,然后转换成mongodb的语法…

      socket.io已经封装的太好了,只要掌握on是接收,emit是发送,双向通信,就可以了,主要复杂的还是前端的逻辑,还好,我前端用jquery库来操作dom。

转载请注明:飞嗨 » node.js聊天室

喜欢 (3)or分享 (0)
发表我的评论
取消评论

表情
粤ICP备15018643号-1