基于node服务器的socket在线聊天室代码解析!

费话不多说,先上图DEMO地址:hemaj.com

**

node服务器代码

**

var WebSocketServer = require('ws').Server;//WebSocketServer模块
var uuid = require('node-uuid');//uuid生成模块
var fs=require("fs");//系统文件模块

var src=require('./app/models/upimg');//自定义保存图片模块调用

var Chatnumber={};//新建聊天室对象

//加载已经建立的聊天室文件
//fs.readFile:异步读取文件
fs.readFile('chat.txt', function (err, data) {
   if (!err){//读取成功时,把取值转化成对像,
        var be=JSON.parse(data.toString());
        for(var i in be){//由于be内部包含对象也要做JSON.parse()解析,
            be[i]=JSON.parse(be[i]);//解析对象中对对象
        }
        Chatnumber=be;
   }
   chatsever();//触发服务事件
});



function chatsever(){
//创建WebSocketServer 服务器,端口为8181;
wss = new WebSocketServer({ port: 8181});
var dataIndex =0;//统计在线人

//connection用于客户端建立tcp连接
wss.on('connection', function (ws) {//ws是当前连用户对象,通信全靠他
    dataIndex += 1;
    console.log('在线总用户:'+dataIndex);    

    //message是收到客户端消息,进行触发
    ws.on('message', function (data){
        data=JSON.parse(data); //data是客户端传过json数据对象
        var id=data['id'];//聊天室ID
        var uid=data['uid'];//用户id
        var state=data['state'];//请求数据类型,0创建聊天房间,1新用户加入,2收到消息,3请求在线人员,4请求聊天室房间列表信息,
        var user=data['user'];//用户信息
        var message=data['text'];//发送内容



        if(!uid){//uid不存时候,创建一个uid
            var client_uuid = uuid.v4();    
        }else{
            client_uuid=uid
        }

        //把用户uid和id储存,在用户关闭时候用
        ws.uid=client_uuid; 
        ws.id=id;

        switch(state){  
            case 0://0创建聊天房间
                var pic=data['pic'];//房间图片
                var title=data['title'];//标题 
                var miaoshu=data['miaoshu'];//描述
                var renshu=data['renshu'];//人数
                var pw=data['pw'];//设置密码

                //src.upimg()封装存图片函数,pic是图片地址或base64
                //imgpath存在服务器的路径设置,function(data){}是回调涵数       
                //data图片储存成功后生成路径
                var imgpath='./Uploads/chatpic/';
                src.upimg(pic,imgpath,function(data){
                    var clients=[];//用天储存用户数组
                    //把创建用户信息存在里去
                    clients.push({'uid':client_uuid, "ws": ws,'user':user});
                    //组建新聊天室数据对象            
                    var obj={'id':id,'clients':clients,'pic':data,'title':title,'miaoshu':miaoshu,'renshu':renshu,'pw':pw};
                    //并且储存Chatnumber对象
                    Chatnumber[id]=obj;
                    var u={'state':0,'uid':client_uuid,'id':id}//返回给客户端数据
                    console.log('创建房间成功'+id);
                    console.log(Chatnumber);
                    ws.send(JSON.stringify(u)); //ws.send()发送给当前用户  
                });
            break;

            case 1://1新用户加入
                if(Chatnumber[id]){
                    //判断当前房间存在
                    var clients=Chatnumber[id]['clients'];
                    var b=false;
                    var index;
                    for(var i in clients){
                        //检查用户uid是否存在房间里
                        if(clients[i]['uid']==client_uuid){
                            b=true;
                            index=i;
                            break;
                        }
                    }
                    if(!b){//有房间时,检查一下该用户存不在
                        //把新用户追加到clients用户组进来
                        clients.push({'uid':client_uuid, "ws": ws,'user':user});
                    }else{//用户存在,重新ws对易县存值
                        clients[index]['ws']=ws;
                        console.log('存在');
                    }
                    //返回数据
                    var u={'state':1,'uid':client_uuid,'title':Chatnumber[id]['title'],'miaoshu':Chatnumber[id]['miaoshu']}
                    ws.send(JSON.stringify(u));//ws.send()发送给当前用户   
                    return false;

                }else{//当房间不存时候,返回数组
                    var u={'state':404,'msg':'当前房间不存在'};
                    ws.send(JSON.stringify(u));//ws.send()发送给当前用户   
                    return false;
                }
            break;

            case 2://2收到消息
                if(message){
                    //message收到消息对象
                    var obj=Chatnumber[id];//获取房间对象
                    var pic=message['pic'];//获取用户发送消息只图片
                    var newpath=[];

                    //发消息只图片存在时,保存服务器,如果你服务器好话,你也可以不存了,直接转发
                    if(pic.length>0){//聊天图片生成
                        var imgpath='./Uploads/chatimg/';//聊天发送图片
                        for(var i in pic){//多张图做个循环生成
                            //生成图片是个异步事件
                            src.upimg(pic[i]['src'],imgpath,function(data){
                                message['pic'][i]['src']=data;//把发送消息对象图片数据转用路径
                                newpath.push(data);
                            });
                        }
                    }
                    //由于是生成图片是个异步事件,做个定时检是否生成完成
                    var t=setTimeout(function(){
                        if(pic.length==newpath.length){
                            //把用户发送消息转发当前房间用户出去
                            //obj当前房对象
                            //message用户发送消息对象
                            //client_uuid发送用户,user发送用信息
                            wsSend(obj,message,client_uuid,user);   
                            clearInterval(t);//停止定时
                        }                       
                    },100); 

                    //收到消息就发送

                }
            break;

            case 3://3请求在线人员
                //取出当前房间人员信息
                var clients=Chatnumber[id]['clients'];
                var attr=[];
                for(var i in clients){//取出房间所有用户信息
                    attr.push(clients[i]['user']);
                }
                var u={'state':3,'clients':attr}
                ws.send(JSON.stringify(u)); //发送给当前用户
                return false;       
            break;

            case 4://4请求聊天室房间列表信息,
                var attr=[];
                //取出所有聊天室信息,并且过滤掉核心内容
                for(var i in Chatnumber){
                    var chatber=new Object();
                    chatber['id']=Chatnumber[i]['id'];//房间id
                    chatber['pic']=Chatnumber[i]['pic'];//房间封面
                    chatber['title']=Chatnumber[i]['title'];//房间标题
                    chatber['miaoshu']=Chatnumber[i]['miaoshu'];//房间描述
                    chatber['renshu']=Chatnumber[i]['renshu'];//能够容多少人
                    chatber['ge']=Chatnumber[i]['clients'].length;//在线多少人
                    attr.push(chatber);
                }

                var u={'state':4,'attr':attr}
                ws.send(JSON.stringify(u)); //发送数据
                return false;       
            break;

        }
        console.log('房间号'+id);
    });


    //当有用户关掉事件,触发
    ws.on('close',function(data){

        dataIndex -= 1; 
        //获取用户id,
        var id=ws.id;
        if(!Chatnumber[id]){return false;}//如果房间不存时,不删除对象
        var uid=ws.uid;//获取用户uid    
        var clients=Chatnumber[id]['clients'];
        for(var i in clients){
                if(clients[i]['uid']==uid){
                    clients.splice(i,1);//删除离开用户ws
                    break;
                }
        }
        console.log('在线总用户:'+dataIndex);
    });

});

}



function wsSend(data,message,uid,user){//发送当前房间所有人发送
    //当前房间用户组(clients)循环发送消息,就是给房间所有用户发一遍消息
    for(var i=0;i<data.clients.length;i++){
        var clientSocket = data.clients[i].ws;
        if(clientSocket.readyState=== 1){//检查用户是否连接
            //发送消息
            clientSocket.send(JSON.stringify({
                'state':2,
                'obj':message,
                'uid':uid,
                'user':user
            }));
        }
    }

}


//服务关掉执行事件
process.on('exit', function(){
         console.log('关闭'); //文件被保
});

//监听服务器ctrl+c事件,当服务器挂把时把Chatnumber聊天房间信息储存起来
//并且生成文件chat.txt,等下次再运行,重新加载文件,防止聊天室房间信息丢掉
process.on('SIGINT', function () {
    var objcc={};
    for(var i in Chatnumber){
        var obja={};
        obja['id']=Chatnumber[i]['id'];
        obja['pic']=Chatnumber[i]['pic'];
        obja['title']=Chatnumber[i]['title'];
        obja['miaoshu']=Chatnumber[i]['miaoshu'];
        obja['renshu']=Chatnumber[i]['renshu'];
        obja['pw']=Chatnumber[i]['pw'];
        obja['clients']=[];
        obja=JSON.stringify(obja);
        objcc[i]=obja;
    }

    var c=JSON.stringify(objcc);
    fs.writeFile('chat.txt',c, function (err) {
         if (err) throw err;
         console.log('保存成功'); //文件被保存   
         process.exit(0);
    }); 
});

可能有一些代码不合理设计,欢迎大家指出。
需要交流和讨论,加QQ群 :293851491

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值