//引入http模块 var socketio = require('socket.io'), fs = require('fs'), https = require('http'), domain = require('domain'), redis = require('redis'), redisio = require('socket.io-redis'), request = require('request'), md5 = require('md5-node'), config = require('./config.js'); var d = domain.create(); d.on("error", function(err) { //console.log(err); }); var sockets = {}; var chat_history={}; var chat_interval={}; /* 主播连麦关系 */ var LiveConnect={}; var LiveConnect_pull={}; // redis 链接 var clientRedis = redis.createClient(config['REDISPORT'],config['REDISHOST']); clientRedis.auth(config['REDISPASS']); //var server = https.createServer(options,function(req, res) { var server = https.createServer(function(req, res) { res.writeHead(200, { 'Content-type': 'text/html;charset=utf-8' }); //res.write("人数: " + numscount ); res.end(); }).listen(config['socket_port'], function() { ////console.log('服务开启19965'); }); var field=[]; var io = socketio.listen(server,{ pingTimeout: 60000, pingInterval: 25000 }); io.on('connection', function(socket) { //console.log(FormatNowDate()); //console.log('连接成功'); //numscount++; var interval; /* 获取服务端配置 */ request(config['WEBADDRESS']+"?service=Home.getFilterField",function(error, response, body){ if(error){ //console.log(error); return; } ; if(!body){ //console.log(body); return; } ; var res = evalJson(body); //console.log(body); //console.log(res.data.info); //console.log("sssss"); field = res.data.info; }); //进入房间 socket.on('conn', function(data) { // console.log('data'); // console.log(data); if(!data || !data.token){ return !1; } userid=data.uid; if(userid<0 && userid==-9999){ //app端 userid=data.mobileid; data.uid=data.mobileid; data.token=data.mobileid; } old_socket = sockets[userid]; if (old_socket && old_socket != socket) { if(data.uid != data.roomnum && data.uid==old_socket.roomnum){ /* 进房间 但旧链接是 主播 */ var data_str='{"retmsg":"ok","retcode":"000000","msg":[{"msgtype":"1","_method_":"StartEndLive","action":"19","ct":"直播关闭"}]}'; old_socket.emit('broadcastingListen',[data_str]); }else if(data.uid== data.roomnum && data.stream==old_socket.stream){ /* 主播重连 */ old_socket.reusing = 1; //console.log("重用"); }else if(data.uid== data.roomnum && data.stream!=old_socket.stream){ /* 主播多端开播 */ var data_str='{"retmsg":"ok","retcode":"000000","msg":[{"msgtype":"1","_method_":"StartEndLive","action":"19","ct":"直播关闭"}]}'; old_socket.emit('broadcastingListen',[data_str]); } old_socket.disconnect() } clientRedis.get(data.token,function(error,res){ if(error){ return; }else if(res==null){ console.log("[获取token失败]"+data.uid); }else{ if(res != null){ var userInfo = evalJson(res); // console.log("用户进入直播间-----------"+res); if(userInfo['id'] == data.uid ){ //console.log("[初始化验证成功]--"+data.uid+"---"+data.roomnum+'---'+data.stream); //获取验证token socket.token = data.token; socket.roomnum = data.roomnum; socket.stream = data.stream; socket.nicename = userInfo['user_nicename']; socket.level = userInfo['level']; socket.avatar = userInfo['avatar']; socket.sign = Number(userInfo['sign']); socket.usertype = parseInt(userInfo['usertype']); socket.uid = data.uid; socket.reusing = 0; socket.join(data.roomnum); sockets[userid] = socket; socket.emit('conn',['ok']); if( socket.roomnum!=socket.uid){ var data_obj={ "msg":[ { "_method_":"SendMsg", "action":"0", "ct":{ "id":''+userInfo['id'], "user_nicename":''+userInfo['user_nicename'], "avatar":userInfo['avatar'], "avatar_thumb":userInfo['avatar_thumb'], "level":''+userInfo['level'], "usertype":''+userInfo['usertype'], }, "msgtype":"0" } ], "retcode":"000000", "retmsg":"OK" }; // console.log(userInfo['usertype']); process_msg(io,socket.roomnum,JSON.stringify(data_obj)); if(socket.stream){ clientRedis.zadd('user_'+socket.stream,socket.sign,userInfo['id']); } } // sendSystemMsg(socket,"直播内容包含任何低俗、暴露和涉黄内容,账号会被封禁;安全部门会24小时巡查哦~"); sendSystemMsg(socket,"欢迎来到直播间,我们倡导绿色直播。直播内容和封面有违法违规、色情低俗、抽烟喝酒、诱导欺诈、聚众闹事等行为账号会被封禁,网警24小时在线巡查哦!"); return; }else{ socket.disconnect(); } } } socket.emit('conn',['no']); }); }); socket.on('broadcast',function(data){ //console.log(data); if(socket.token != undefined){ var dataObj = typeof data == 'object'?data:evalJson(data); var msg = dataObj['msg'][0]; var token = dataObj['token']; var method = msg['_method_']; var action = msg['action']; var data_str = typeof data == 'object'?JSON.stringify(data):data; switch(method){ case 'SendMsg':{ //聊天 dataObj['msg'][0]['ct']=filter(dataObj['msg'][0]['ct']); clientRedis.hget( "super",socket.uid,function(error,res){ if(error) return; if(res != null){ var data_str2={ "msg":[ { "_method_":"SystemNot", "action":"1", "ct":''+dataObj['msg'][0]['ct'], "msgtype":"4" } ], "retcode":"000000", "retmsg":"OK" }; process_msg(io,socket.roomnum,JSON.stringify(data_str2)); }else{ data_str=JSON.stringify(dataObj); clientRedis.hget(socket.roomnum + "shutup",socket.uid,function(error,res){ if(error) return; if(res != null){ var newData = dataObj; newData['retcode'] = '409002'; socket.emit('broadcastingListen',[JSON.stringify(newData)]); }else{ process_msg(io,socket.roomnum,data_str); } }); } }); break; } case 'SendGift':{ //送礼物 var gifToken = dataObj['msg'][0]['ct']; console.log('送礼物gifToken'); console.log(gifToken); clientRedis.get(gifToken,function(error,res){ console.log('get送礼物'); console.log(error); console.log(res); if(!error&&res != null){ var sendGiftObj = evalJson(res); console.log(sendGiftObj); var len=sendGiftObj.length; for (var i = 0; i < len; i++) { var resObj= sendGiftObj[i]; dataObj['msg'][0]['ct'] = resObj; io.sockets.in(socket.roomnum).emit('broadcastingListen',[JSON.stringify(dataObj)]); } clientRedis.del(gifToken); } }); break; } case 'SendBarrage':{ //弹幕 var barragetoken = dataObj['msg'][0]['ct']; clientRedis.get(barragetoken,function(error,res){ if(!error&&res != null){ var resObj = evalJson(res); var con=resObj.content; var res = filter(con); resObj.content=res; dataObj['msg'][0]['ct'] = resObj; var data_str=JSON.stringify(dataObj); process_msg(io,socket.roomnum,data_str); clientRedis.del(barragetoken); } }); break; } case 'light' :{ //点亮 process_msg(io,socket.roomnum,data_str); break; } case 'updateVotes' :{//更新映票 process_msg(io,socket.roomnum,data_str); break; } case 'StartEndLive':{ if(socket.usertype == 50 ){ socket.broadcast.to(socket.roomnum).emit('broadcastingListen',[data_str]); }else{ clientRedis.get("LiveAuthority" + socket.uid,function(error,res){ if(error) return; if(parseInt(res) == 5 ||parseInt(res) == 1 || parseInt(res) == 2){ socket.broadcast.to(socket.roomnum).emit('broadcastingListen',[data_str]); } }) } break; } case 'SystemNot':{//系统通知 process_msg(io,socket.roomnum,data_str); break; } } } }); socket.on('superadminaction',function(data){ if(data['token'] == config['TOKEN']){ io.sockets.in(data['roomnum']).emit("broadcastingListen", ['stopplay']); } }); /* 系统信息 */ socket.on('systemadmin',function(data){ if(data['token'] == config['TOKEN']){ var data_obj={ "msg":[ { "_method_":"SystemNot", "action":"1", "ct":''+ data.content, "msgtype":"4" } ], "retcode":"000000", "retmsg":"OK" }; io.emit('broadcastingListen',[JSON.stringify(data_obj)]); } }); //资源释放 socket.on('disconnect', function() { if(socket.roomnum ==null || socket.token==null || socket.uid <=0){ return !1; } d.run(function() { if(socket.roomnum==socket.uid){ /* 主播 */ if(socket.reusing==0){ request(config['WEBADDRESS']+"?service=Live.stopRoom&uid="+socket.uid + "&token=" + socket.token+ "&type=1&source=socket&stream=" + socket.stream,function(error, response, body){ var data_obj={ "retmsg":"ok", "retcode":"000000", "msg":[ { "msgtype":"1", "_method_":"StartEndLive", "action":"18", "ct":"直播关闭" } ] }; process_msg(io,socket.roomnum,JSON.stringify(data_obj)); // console.log('关播'); // console.log(FormatNowDate()); // console.log('uid---'+socket.uid); }); endLiveConnect(io,socket.uid); } }else{ /* 观众 */ clientRedis.zrem('user_'+socket.stream,socket.uid,function(error,res){ if(error) return; if(res){ var data_obj={ "msg":[ { "_method_":"disconnect", "action":"1", "ct":{ "id":''+socket.uid, "user_nicename":''+socket.nicename, "avatar":socket.avatar, "level":''+socket.level }, "msgtype":"0", "uid":''+socket.uid, "uname":socket.nicename } ], "retcode":"000000", "retmsg":"OK" }; process_msg(io,socket.roomnum,JSON.stringify(data_obj)); } }); clientRedis.del(socket.token); clientRedis.hdel('super',socket.uid); } ////console.log(socket.roomnum+"==="+socket.token+"===="+socket.uid+"======"+socket.stream); socket.leave(socket.roomnum); delete io.sockets.sockets[socket.id]; sockets[socket.uid] = null; delete sockets[socket.uid]; }); }); }); function sendSystemMsg(socket,msg){ var data_obj={ "msg":[ { "_method_":"SystemNot", "action":"1", "ct":""+ msg, "msgtype":"4" } ], "retcode":"000000", "retmsg":"OK" }; socket.emit('broadcastingListen',[JSON.stringify(data_obj)]); } function evalJson(data){ return eval("("+data+")"); } function process_msg(io,roomnum,data){ if(!chat_history[roomnum]){ chat_history[roomnum]=[]; } chat_history[roomnum].push(data); chat_interval[roomnum] || (chat_interval[roomnum]=setInterval(function(){ if(chat_history[roomnum].length>0){ send_msg(io,roomnum); }else{ clearInterval(chat_interval[roomnum]); chat_interval[roomnum]=null; } },200)); } function send_msg(io,roomnum){ var data=chat_history[roomnum].splice(0,chat_history[roomnum].length); io.sockets.in(roomnum).emit("broadcastingListen", data); } //时间格式化 function FormatNowDate(){ var mDate = new Date(); var Y = mDate.getFullYear(); var M = mDate.getMonth()+1; var D = mDate.getDate(); var H = mDate.getHours(); var i = mDate.getMinutes(); var s = mDate.getSeconds(); return Y +'-' + M + '-' + D + ' ' + H + ':' + i + ':' + s; } /* sign加密 */ function setSign(obj) {//排序的函数 var str=''; var newkey = Object.keys(obj).sort(); //先用Object内置类的keys方法获取要排序对象的属性名,再利用Array原型上的sort方法对获取的属性名进行排序,newkey是一个数组 var newObj = {};//创建一个新的对象,用于存放排好序的键值对 for (var i = 0; i < newkey.length; i++) {//遍历newkey数组 //newObj[newkey[i]] = obj[newkey[i]];//向新创建的对象中按照排好的顺序依次增加键值对 str+=newkey[i]+'='+obj[newkey[i]]+'&'; } str+=config['sign_key']; var sign=md5(str); return sign; } //过滤函数 function filter(str) { // 多个敏感词,这里直接以数组的形式展示出来 var arrMg = field; //console.log(arrMg); // 显示的内容--showContent var showContent = str; //console.log(showContent); // 正则表达式 // \d 匹配数字 for (var i = 0; i < arrMg.length; i++) { // 创建一个正则表达式 var r = new RegExp(arrMg[i], "ig"); var re=''; for(var n=0;n