聊天系统 websocket 直播聊天
小结:
1、
一个HTTP连接在长时间没有数据传输的情况下,链路上的任何一个网关都可能关闭这个连接,而网关是我们不可控的
websocket
http://kai.yilaizhibo.com/js/controller.js http://kai.yilaizhibo.com/js/controller.js
$(function(){ init(); $(document).on("dblclick",".liaotian_right div",function(){ $.fancybox($(this).html().replace("max-width:500px; max-height:600px",""), { scrolling: "no", padding: 20, transitionIn: "none", transitionOut: "none" }); }); var $_GET = (function(){ var url = window.document.location.href.toString(); var u = url.split("?"); if(typeof(u[1]) == "string"){ u = u[1].split("&"); var get = {}; for(var i in u){ var j = u[i].split("="); get[j[0]] = j[1]; } return get; } else { return {}; } })(); if(ADMINID==14){ if(VIEWSTATUS!='0'){ setTimeout('clearVideo()',60*VIEWTIME*1000); }} $(".zaixian_tit a").click(function(){ $(".zaixian_tit a").removeClass("on"); $(this).addClass("on"); if($.trim($("#user_select.on").text())=="我的客户"){ $('#users_online li').each(function(){ if($(this).attr('tuijianmid')!=MID){ $(this).hide(); } }); }else if($.trim($("#user_select.on").text())=="我的客服"){ $('#users_online li').each(function(){ if($(this).attr('uid')!=TUIJIANMID){ $(this).hide(); } }); }else{ $('#users_online').show(); // $('#mykefu').hide(); $('#users_online li').show(); } }); $("#liaotianlist").scroll( function() { var viewH =$(this).height(); var contentH =$(this).scrollHeight;//内容高度 var scrollTop =$(this).scrollTop(); if(viewH>=scrollTop){ $(".load_more").show('fast') }else{ $(".load_more").hide('fast') } } ); $("#role_select").change(function(){ var _aid=$("#role_select>option[value='"+$(this).val()+"']").attr("aid"); if(_aid=='1'){ $('.bar_quanping[id=gundong]').show(); }else { $('.bar_quanping[id=gundong]').hide(); } }); }); function formatDate(now) { var year=now.getYear(); var month=now.getMonth()+1; var date=now.getDate(); var hour=now.getHours(); var minute=now.getMinutes(); var second=now.getSeconds(); if(hour<10){ hour='0'+hour; } if(minute<10){ minute='0'+minute; } if(second<10){ second='0'+second; } return hour+":"+minute; } function init() { ws = new WebSocket("ws://"+WS_HOST+":"+WS_PORT); // 创建websocket // 当socket连接打开时,输入用户名 ws.onopen = function() { timeid && window.clearInterval(timeid); if(!USERNAME) { window.location.reload(); return ws.close(); } if(reconnect == false) { // 登录 var login_data = JSON.stringify({"type":"login","client_name":USERNAME,"room_id":FID,"mid":MID,"adminid":ADMINID,"dzip":DZIP,"tuijianmid":TUIJIANMID,"tuijianusername":TUIJIANUSERNAME,"tuijianadminid":TUIJIANADMINID,"login_count":LOGIN_COUNT,"LOGIN_SWITCH":LOGIN_SWITCH}); // console.log("websocket握手成功,发送登录数据:"+login_data); ws.send(login_data); reconnect = true; } else { // 断线重连 var relogin_data = JSON.stringify({"type":"login","client_name":USERNAME,"room_id":FID,"mid":MID,"adminid":ADMINID,"dzip":DZIP,"tuijianmid":TUIJIANMID,"tuijianusername":TUIJIANUSERNAME,"tuijianadminid":TUIJIANADMINID,"login_count":LOGIN_COUNT}); console.log("websocket握手成功,发送重连数据:"+relogin_data); ws.send(relogin_data); } }; // 当有消息时根据消息类型显示不同信息 ws.onmessage = function(e) { //console.log(e); var data = JSON.parse(e.data); //console.log(e); switch(data.type){ // 服务端ping客户端 case 'ping': ws.send(JSON.stringify({"type":"pong"})); break;; // 登录 更新用户列表 case 'login': if(ADMINID==1 && LOGIN_TIP==1){ $('#liaotianlist').append( '<div class="liaotian"> <div class="liaotian_right fl"><div>'+ data.client_name+'大步来到赛场!</div></div></div>' ); } if($("#liaotianlist .liaotian").length>30){ $("#liaotianlist .liaotian:lt(1)").remove(); } if($('.bar_gundong').attr('checked')){ $('#liaotianlist').animate( { scrollTop: $('#liaotianlist')[0].scrollHeight } ,1000 ); } // 登录请求是自己发的 就全量。 是别人发的 就增量 if( data.client_name == USERNAME){ flush_client_list(data.client_list); }else{ flush_client_list_add(data.client_item); } break; // 断线重连,只更新用户列表 case 're_login': flush_client_list(data.client_list); console.log(data['client_name']+"重连成功"); break; // 登录出错 /*case 'login_error': alert('对不起,系统检测您的账号已处于登录状态'); window.location.href='/sys/off.php'; break;*/ // 发言 case 'say': //{"type":"say","from_client_id":xxx,"to_client_id":"all/client_id","content":"xxx","time":"xxx"} say(data); break; // 私聊 case 'siliao': //{"type":"say","from_client_id":xxx,"to_client_id":"all/client_id","content":"xxx","time":"xxx"} siliao(data); break; // 通知直播间中iframe 切换主播 case 'switchAnchor': if($("#video-win").length>0 && data.uid){ $('#video-win iframe').contents().find('iframe').attr('src', 'http://www.zhiniu8.com/h5live?uid='+data.uid); } break; case 'pubclear': $('#liaotianlist').html(''); break; case 'tuijian': if(ADMINID==14 && TUIJIANMID!=data.mid && data.mid){ TUIJIANMID=data.mid; $.get("action.php?type=changetuijian",{mid:data.mid},function(data,status){}); } break; case 'deleteliaotian': $("#"+data.lid).remove(); break; case 'logout': if(ADMINID==1 && LOGIN_TIP==1){ $('#liaotianlist').append( '<div class="liaotian"> <div class="liaotian_right fl"><div>'+data['from_client_name']+'怀揣着炒股秘籍,依依不舍的离开了!</div></div></div>' ); } $("#users_online li").each(function(){ if ( $(this).attr('uid') ==data.mid) { $(this).remove(); return false; } }); // console.log(data.client_list); flush_client_list(data.client_list); $(".renshu b").html(parseInt($(".renshu").attr('rel'))+parseInt($("#users_online li").length)); $(".renshu sj span").html(parseInt($("#users_online li").length)) } }; ws.onclose = function() { console.log("连接关闭,定时重连"); // 定时重连 window.clearInterval(timeid); timeid = window.setInterval(init, 3000); }; ws.onerror = function() { // alert("出现错误"); window.setTimeout(init, 3000); }; } function clearVideo(){ video_html = '<p>对不起,您的观看时间已到,请联系客服后继续观看</p>'; $(".shipinchuangkou").html(video_html); $.cookie('clearvideo',true,{expires:1}); } function switchAnchor(jid){ ws. send(JSON.stringify({"type":"switchAnchor","uid":jid}));//socket发送 uid 切换直播iframe url } function addliaotian(siliao){ WAIT=FAYAN_LIMIT; var tomid,tousername; if(ADMINID==14 && WAIT>0 && WAIT!=FAYAN_LIMIT){ $("#ts").click(); return false; } if(ADMINID!=1 && ADMINID!=2){ var content=$('#send_input').val(); $('#send_input').val(''); }else{ var content=UE.getEditor('send_input').getContent(); UE.getEditor('send_input').setContent(''); } tomid=TOMID; tousername=TOUSERNAME; if(siliao===1){ content=$('#Y_iSend_Input2').text(); $('#Y_iSend_Input2').html(''); }else{ tomid=$('#send_talkto').val(); tousesrname=$('#send_talkto').attr('uname'); siliao=0; } var quanping=$('.bar_quanping').attr('checked')?1:0; if(!content){ return false; } var roleid=$("#role_select option:selected").attr('uid'); var rolename=$("#role_select").val(); var roleaid=$("#role_select option:selected").attr('aid'); $.ajax({ url: "action.php?type=addliaotian", type: "POST", async: true, data:{content:content,username:USERNAME,mid:MID,tomid:tomid,tousername:tousername,siliao:siliao,roleid:roleid,rolename:rolename,roleaid:roleaid}, dataType: "json", error: function(){ // alert('Error loading XML document'); }, success: function(data){//如果调用php成功 if(data.content){ console.log(siliao); if(siliao===1){ ws.send(JSON.stringify({"type":"siliao","tomid":data.tomid,"tousername":data.tousername,"toadminid":data.toadminid,"content":data.content})); }else{ if(quanping){ data.quanping=1; } say(data); ws.send(JSON.stringify({"type":"say","tomid":data.tomid,"tousername":data.tousername,"toadminid":data.toadminid,"lid":data.lid,"quanping":quanping,"content":data.content2,"shstatus":data.shstatus,"roleid":roleid,"rolename":rolename,"roleaid":roleaid}));//socket发送公聊信息//socket发送公聊信息 } }else if(data=='iphei'){ window.location.reload(); }else if(data=='shenhe'){ notice('消息审核中。。。'); }else if(!isNaN(data)){ WAIT=data; $("#ts").click(); }else if(data=='jinyan'){ notice('对不起,您所在的用户组不允许发言'); } } }); if(!limitCount){ limitCount= setInterval(fayanLimit,1000); } } // 新增用户到 用户列表 function flush_client_list_add(client) { var v = client; if($("#users_online li[uid='"+v['mid']+"']").length>0){ $("#users_online li[uid='"+v['mid']+"'] .u_l").html('('+v['login_count']+')'); return true; } var hasInsert=0; var user_pingbi=''; var userhide=''; if(ADMINID==3 && $.trim($("#user_select.on").text())=="我的客户" && v['tuijianmid']!=MID){ var userhide='style="display:none"'; } if(ADMINID=='1'){ var u_l='<span class="u_l">('+v['login_count']+')</span>'; var ban_str='<a href="javascript:void(0)" class="ipban" onclick="ipban(\''+v['mid']+'\')">封IP</a><a class="pingbi">屏蔽</><a href="javascript:void(0)" onclick="pingbi(1)">1小时/</a> <a href="javascript:void(0)" onclick="pingbi(2)">1天/</a><a href="javascript:void(0)" onclick="pingbi(3)">1周/</a><a href="javascript:void(0)" onclick="pingbi(4)">1个月</a><a href="javascript:void(0)" >'+v['dzip']+'</a>'; }else if(ADMINID=='2'){ var u_l=''; var ban_str='<a href="javascript:void(0)" class="ipban" onclick="ipban(\''+v['mid']+'\')">封IP</a><a class="pingbi">屏蔽</><a href="javascript:void(0)" onclick="pingbi(1)">1小时/</a> <a href="javascript:void(0)" onclick="pingbi(2)">1天/</a><a href="javascript:void(0)" onclick="pingbi(3)">1周/</a><a href="javascript:void(0)" onclick="pingbi(4)">1个月</a>'; }else if(ADMINID=='3'){ var u_l='<span class="u_l">('+v['login_count']+')</span>'; var ban_str='<a class="pingbi">屏蔽</><a href="javascript:void(0)" onclick="pingbi(1)">1小时/</a> <a href="javascript:void(0)" onclick="pingbi(2)">1天/</a><a href="javascript:void(0)" onclick="pingbi(3)">1周/</a><a href="javascript:void(0)" onclick="pingbi(4)">1个月</a>'; }else{ var u_l=''; var ban_str=''; } var str ='<li uid="'+v['mid']+'" uname="'+v['client_name']+'" adminid="'+v['adminid']+'" tuijianmid="'+v['tuijianmid']+'" onclick="UBase_Click(this)" '+userhide+'> <a href="javascript:void(0)">'+v['client_name']+u_l+'</a> <span><img src="images/level/vip'+v['adminid']+'.png"></span> <p><a href="javascript:void(0)" class="talkto" onclick="sayTo(this)">对TA说</a>'+ban_str+'</p></li>'; if($("#users_online li").length>0){ $("#users_online li").each(function(){ if(parseInt($(this).attr('adminid'))> parseInt(v['adminid'])){ $(this).before(str); hasInsert=1;//标记是否插入数据 return false; } }); } if(!hasInsert){ $("#users_online").append(str); } $(".renshu b").html(parseInt($(".renshu").attr('rel'))+parseInt($("#users_online li").length)); $(".renshu sj span").html(parseInt($("#users_online li").length)) } // 刷新用户列表框 function flush_client_list(client_list){ if ( !client_list ) { return false; } $.each( client_list, function( k, v ){ if($("#users_online li[uid='"+v['mid']+"']").length>0){ $("#users_online li[uid='"+v['mid']+"'] .u_l").html('('+v['login_count']+')'); return true; } var hasInsert=0; var user_pingbi=''; var userhide=''; if(ADMINID==3 && $.trim($("#user_select.on").text())=="我的客户" && v['tuijianmid']!=MID){ var userhide='style="display:none"'; } if(ADMINID=='1'){ var u_l='<span class="u_l">('+v['login_count']+')</span>'; var ban_str='<a href="javascript:void(0)" class="ipban" onclick="ipban(\''+v['mid']+'\')">封IP</a><a class="pingbi">屏蔽</><a href="javascript:void(0)" onclick="pingbi(1)">1小时/</a> <a href="javascript:void(0)" onclick="pingbi(2)">1天/</a><a href="javascript:void(0)" onclick="pingbi(3)">1周/</a><a href="javascript:void(0)" onclick="pingbi(4)">1个月</a><a href="javascript:void(0)" >'+v['dzip']+'</a>'; }else if(ADMINID=='2'){ var u_l=''; var ban_str='<a href="javascript:void(0)" class="ipban" onclick="ipban(\''+v['mid']+'\')">封IP</a><a class="pingbi">屏蔽</><a href="javascript:void(0)" onclick="pingbi(1)">1小时/</a> <a href="javascript:void(0)" onclick="pingbi(2)">1天/</a><a href="javascript:void(0)" onclick="pingbi(3)">1周/</a><a href="javascript:void(0)" onclick="pingbi(4)">1个月</a>'; }else if(ADMINID=='3'){ var u_l='<span class="u_l">('+v['login_count']+')</span>'; var ban_str='<a class="pingbi">屏蔽</><a href="javascript:void(0)" onclick="pingbi(1)">1小时/</a> <a href="javascript:void(0)" onclick="pingbi(2)">1天/</a><a href="javascript:void(0)" onclick="pingbi(3)">1周/</a><a href="javascript:void(0)" onclick="pingbi(4)">1个月</a>'; }else{ var u_l=''; var ban_str=''; } var str ='<li uid="'+v['mid']+'" uname="'+v['client_name']+'" adminid="'+v['adminid']+'" tuijianmid="'+v['tuijianmid']+'" onclick="UBase_Click(this)" '+userhide+'> <a href="javascript:void(0)">'+v['client_name']+u_l+'</a> <span><img src="images/level/vip'+v['adminid']+'.png"></span> <p><a href="javascript:void(0)" class="talkto" onclick="sayTo(this)">对TA说</a>'+ban_str+'</p></li>'; if($("#users_online li").length>0){ $("#users_online li").each(function(){ if(parseInt($(this).attr('adminid'))> parseInt(v['adminid'])){ $(this).before(str); hasInsert=1;//标记是否插入数据 return false; } }); } if(!hasInsert){ $("#users_online").append(str); } }); $(".renshu b").html(parseInt($(".renshu").attr('rel'))+parseInt($("#users_online li").length)); $(".renshu sj span").html(parseInt($("#users_online li").length)) } // 发言 function say(data){ // console.info(data); var t = $('#liaotianlist'); var d=new Date(parseInt(data.time)*1000); var shijian=formatDate(d); var sh_str=''; if((ADMINID==3 || ADMINID==1) && data.shstatus=="0"){ sh_str='<a href="javascript:void(0)" rel="'+data.lid+'" onclick="liaotianShenhe(this)" class="lt_sh">审核</a>' } if(ADMINID==3 || ADMINID==1){ sh_str+='<a href="javascript:void(0)"; rel="'+data.lid+'" onclick="liaotianDel(this)" class="lt_del">删除</a> <a href="javascript:void(0)" rel="'+data.mid+'" onclick="getUserInfo(this)" class="lt_xq">详情信息</a>' } if((ADMINID==3 || ADMINID==1) && data.shstatus=="1"){ if($(".lt_sh[rel='"+data.lid+"']").length>0){ $(".lt_sh[rel='"+data.lid+"']").remove(); return false; } } if(!(ADMINID==3 || ADMINID==1) && data.shstatus=="0"){ return false; } if($(".liaotian[id='"+data.lid+"']").length>0 && data.lid){ return false; } if( data.username!='交易提示' && data.username!='系统提示'){ if(data.tomid && data.tomid!="null" && data.tomid!="undefined" && data.tomid!="0"){ To_str='<a class="user_to">对</a><img src="images/level/User'+data.toadminid+'.png"/><a href="javascript:void)(0)" uid="'+data.tomid+'" uname="'+data.tousername+'" onclick="User_Click(this)">'+data.tousername+'</a>'; }else{ var To_str=''; } var redbagdiv=''; if(data.msgtype==2){ play('mp3/5103.mp3'); redbagdiv="redbagdiv"; } var str ='<div class="liaotian" id="'+data.lid+'" aid="'+data.adminid+'"><div class="liaotian_right fl '+redbagdiv+'"><Span class="userbase"><a class="usertime" href="javascript:void(0)">['+shijian+']</a><img src="images/level/User'+data.adminid+'.png"> <a class="usertubiao" href="javascript:void)(0)" uid="'+data.mid+'" uname="'+data.username+'" onclick="User_Click(this)">'+data.username+'</a>'+To_str+sh_str+'</Span><div>'+data.content+'</div></div> </div>'; }else{ if(data.username=='交易提示'){ play('mp3/5103.mp3'); var click_str='onclick="$(\'#hdtx\').click()"'; var str ='<div class="liaotian "> <div class="liaotian_right fl m2"><span class="userbase "><a href="javascript:void)(0)" uid="8" uname="'+data.username+'" >'+data.username+' </a><a href="javascript:void(0)">['+shijian+']</a></span> <div '+click_str+'>'+data.content+'</div></div> </div>'; }else{ var str ='<div class="liaotian "> <div class="liaotian_right fl m3"> <div >'+data.content+'</div></div> </div>'; } } t.append(str); if($("#liaotianlist .liaotian").length>30){ $("#liaotianlist .liaotian:lt(1)").remove(); } if($('.bar_gundong').attr('checked')){ t.animate( { scrollTop: t[0].scrollHeight } ,1000 ); } if(data.quanping){ $('.quanping').append('<div>'+data.content.replace(/<[^>]+>/g,"")+'</div>'); init_screen() } } function siliao(data){ $(".loading").hide() var t = $('#liaotianlist'); tomid=TOMID; tousername=TOUSERNAME; var d=new Date(parseInt(data.time)*1000); var shijian=formatDate(d); if(data.mid==tomid || data.tomid==tomid ){ var str=' <div class="liaotian"> <div class="liaotian_left fl"><img src="images/level/User'+data.adminid+'.png"></div> <div class="liaotian_right fl"><Span>'+data.username+' 对 '+data.tousername+' ['+shijian+'"]</Span><div>'+data.content+'</div> </div> </div>'; $("#Y_PriMes_Div ").append(str); }else{ var uid= (MID==data.tomid)?data.mid: data.tomid; var uname= (USERNAME==data.tousername)?data.username:data.tousername; var hassiliao=$(".l-tab-links ul li[uid='"+uid+"']"); if(hassiliao.length==0){ if($(".l-tab-links ul li").length==0){//no body TOMID=uid; TOUSERNAME=uname; // sayTo(); var str='<li tabid="" class="l-selected" style="cursor: pointer;" uid="'+TOMID+'" uname="'+TOUSERNAME+'" > <a style="line-height:31px;" onclick="UBase_Click2(this);sayTo();">'+TOUSERNAME+'</a> <div class="l-tab-links-item-left"></div><div class="l-tab-links-item-right"></div> <div class="l-tab-links-item-close" onclick="RemovePrivatePerson(this)"></div></li>'; var c_str=' <div class="liaotian"> <div class="liaotian_left fl"><img src="images/level/User'+data.adminid+'.png"></div> <div class="liaotian_right fl"><Span>'+data.username+' 对 '+data.tousername+' ['+shijian+'"]</Span><div>'+data.content+'</div> </div> </div>'; $("#Y_PriMes_Div ").append(c_str); }else{ var str='<li tabid="" class="" style="cursor: pointer;" uid="'+uid+'" uname="'+uname+'" onclick="$(this).addClass(\'l-selected\');"> <a style="line-height:31px;color:red" onclick="UBase_Click2(this);sayTo();">'+uname+'</a> <div class="l-tab-links-item-left"></div><div class="l-tab-links-item-right"></div> <div class="l-tab-links-item-close" onclick="RemovePrivatePerson(this)"></div></li>'; } $(".l-tab-links ul").append(str); }else{ hassiliao.find('a').css("color","red"); } } if($(".whisper").is(":hidden")) { $(".whisper").show(); } if($("#Y_PriMes_Div .liaotian").length>30){ $("#Y_PriMes_Div .liaotian:lt(1)").remove(); } $("#Y_PriMes_Div ").animate( { scrollTop: $("#Y_PriMes_Div ")[0].scrollHeight } ,100 ); } function fayanLimit(){ $('.tishi_content t').html(WAIT); WAIT--; if(WAIT==0){ clearInterval(limitCount); limitCount=''; $.fancybox.close(); WAIT=FAYAN_LIMIT; } } function notice(content){ $("#qtip-growl-container").qtip({ content: {text: content,title: "提示" }, corner: { target: 'bottomRight', tooltip: 'topLeft' }, style: { classes: 'qtip-dark qtip-shadow qtip-rounded' }, show: { ready:true , effect: function() { $(this).slideDown(); } }, hide: { event: false, inactive: 5000, effect: function() { $(this).slideUp(); } } }); } function getSiliaodata(){ var tomid=TOMID; var tousername=TOUSERNAME; $.ajax({ url: "action.php?type=getSiliaodata", type: "POST", data:{mid:MID,tomid:tomid}, timeout:8000, dataType: "json", cache:false, success: function(msg){//msg为返回的数据,在这里做数据绑定 $(".loading").hide(); $('#Y_PriMes_Div .liaotian').remove(); if(msg instanceof Array){ for(i in msg){ siliao(msg[i]); } } }, error:function(XMLHttpRequest,textStatus,errorThrown){ } }); } function pingbi(t){ if(!window.confirm("确认屏蔽此人?")) { return false; } if(ADMINID<=3){ $.ajax({ url: "action.php?type=pingbi", type: "POST", async: true, data:{mid:TOMID,t:t}, //dataType: "json", error: function(){ // alert('Error loading XML document'); }, success: function(data){//如果调用php成功 if(data=="true"){ notice("屏蔽成功"); }else{ notice("屏蔽失败"); } } }); }else{ notice('您不具有此权限'); } } function ipban(){ if(!window.confirm("确认封掉此人IP?")) { return false; } if(ADMINID<=3){ $.ajax({ url: "action.php?type=ipban", type: "POST", async: true, data:{mid:TOMID}, //dataType: "json", error: function(){ // alert('Error loading XML document'); }, success: function(data){//如果调用php成功 if(data=="true"){ notice("屏蔽成功"); }else{ notice("屏蔽失败"); } } }); }else{ notice('您不具有此权限'); } } function liaotianShenhe(e){ $.ajax({ url: "action.php?type=updateliaotian", type: "POST", data:{lid:e.rel}, timeout:8000, dataType: "json", cache:false, success: function(msg){//msg为返回的数据,在这里做数据绑定 if(typeof(msg) == "object"){ var lid=msg.lid; var sh_mid=msg.mid; var username=msg.username; var adminid=msg.adminid; var sh_tomid=msg.tomid; var tousername=msg.tousername; var toadminid=msg.toadminid; var sh_content=msg.content; ws.send(JSON.stringify( {"type":"shenhe","lid":lid, "mid" : sh_mid,"adminid":adminid,"username":username,"tomid":sh_tomid,"tousername":tousername,"toadminid":toadminid,"shstatus":1,"sh_content":sh_content,"fid":FID } ) ); $(e).remove(); }else if(msg=='yishenhe'){ $(e).remove(); }else{ notice('操作失败'); } }, error:function(XMLHttpRequest,textStatus,errorThrown){ } }); } function liaotianDel(e){ $.ajax({ url: "action.php?type=deleteliaotian", type: "POST", data:{lid:e.rel}, timeout:8000, dataType: "json", cache:false, success: function(msg){//msg为返回的数据,在这里做数据绑定 if(typeof(msg) == "object"){ var lid=msg.lid; ws.send(JSON.stringify( {"type":"deleteliaotian","lid":lid,"fid":FID } ) ); $("#"+lid).remove(); }else{ notice('操作失败'); } }, error:function(XMLHttpRequest,textStatus,errorThrown){ } }); } function SendFlower(jid){ if(!Flower_NUM){ notice('对不起,您没有足够的红包'); return false; } var _jr_name=$('#role_select').val(); $.ajax({ url: "action.php?type=sendflower", type: "POST", async: true, data:{jid:jid,jiaren:_jr_name}, dataType: "json", error: function(){ // alert('Error loading XML document'); }, success: function(data){//如果调用php成功 if(data!="false"){ notice("送花成功"); $('.FlowerNum span').html(data.num); Flower_NUM--; $(".bar_flower span").html(Flower_NUM); ws.send(JSON.stringify( {"type":"sendflower","sh_content":data.content} ) ); }else{ notice("您已经没有花了"); } } }); } function GetFlower(){ $.get("action.php?type=getflower",function(data,status){ if(!isNaN(data)){ Flower_NUM=data; }else{ setTimeout("GetFlower",1000); } }); } function addFlower(){ Flower_NUM++; $(".bar_flower span").html(Flower_NUM); $.get("action.php?type=addflower&mid="+MID,function(data,status){}); } function setTeacherId(mid){ $.get("action.php?type=setteacherid&mid="+mid,function(data,status){ if(!isNaN(data)){ $('.RegBagNum span').html(data); } }); } function loadMore(){ var load_more=$(".load_more"); $(".load_more a").addClass('wait'); $(".load_more a").text(''); var lid=$("#liaotianlist .liaotian[id!='']:first").attr('id'); $.get("action.php?type=loadmore&lid="+lid,function(msg,status){ if(msg!='false'){ for(i in msg){ data=msg[i]; if(data.tomid && data.tomid!="null" && data.tomid!="undefined" && data.tomid!="0"){ var To_str='<a class="user_to">对</a><img src="images/level/User'+data.toadminid+'.png"/><a href="javascript:void)(0)" uid="'+data.tomid+'" uname="'+data.tousername+'" onclick="User_Click(this)">'+data.tousername+'</a>'; }else{ var To_str=''; } var d=new Date(parseInt(data.time)*1000); var shijian=formatDate(d); var redbagdiv=data.msgtype==2?'redbagdiv':''; var str ='<div class="liaotian" id="'+data.lid+'" aid="'+data.adminid+'"> <div class="liaotian_right fl '+redbagdiv+'"> <Span class="userbase"> <a class="usertime" href="javascript:void(0)">['+shijian+']</a> <img src="images/level/User'+data.adminid+'.png"> <a class="usertubiao" href="javascript:void)(0)" uid="'+data.mid+'" uname="'+data.username+'" onclick="User_Click(this)">'+data.username+'</a> </span> <div>'+data.content+'</div></div></div>'; $('#liaotianlist').prepend(str); } $(".load_more a").removeClass('wait'); $(".load_more a").text('查看更多信息'); $('#liaotianlist').prepend(load_more); $('#liaotianlist').scrollTop($("#liaotianlist .liaotian[id='"+lid+"']").offset().top); }else{ //alert('加载失败'); } },'json'); } function loadykmore(){ var uid=$("#users_online li[uid!='']:last").attr('uid'); $.get("action.php?type=loadykmore&uid="+uid,function(msg,status){ if(msg!='false'){ for(i in msg){ data=msg[i]; var d=new Date(parseInt(data.time)*1000); var shijian=formatDate(d); var redbagdiv=data.msgtype==2?'redbagdiv':''; var str ='<li uid="'+data.mid+'" uname="'+data.username+'" adminid="'+data.adminid+'" tuijianmid="'+data.tuijianmid+'" onclick="UBase_Click(this)"><a href="javascript:void(0)">'+data.username+'</a><span><img src="images/level/vip'+data.adminid+'.png" ></span><p><a href="javascript:void(0)" class="talkto" onclick="sayTo()">对TA说</a></p></li>'; $('#users_online').append(str); } $(".loadykmore a").removeClass('wait'); $(".loadykmore a").text('查看更多信息'); }else{ // alert('加载失败'); } },'json'); } function changeSkin(e){ $('#skin img').attr('src',e.rel); $.cookie('bg_img',e.rel, {expires: 365, path: '/'}); $("#skin img").attr("src",e.rel); } function getUserInfo(e){ $.get("action.php?type=getuserinfo&mid="+e.rel,function(data,status){ if(data){ $(e).html('Dzip:'+data.dzip+',IP:'+data.ip+',注册时间:'+data.regtime+',备注:'+data.beizhu); } },'json'); } function sendRedbag(){ var _num=$("#rendbag_num").val(); var _total=$('#rendbag_total').val(); var roleid=$("#role_select option:selected").attr('uid'); var rolename=$("#role_select").val(); var roleaid=$("#role_select option:selected").attr('aid'); $.ajax({ url: "action.php?type=sendredbag", type: "POST", async: true, data:{num:_num,total:_total}, dataType: "json", error: function(){ }, success: function(data){//如果调用php成功 if(typeof(data) == "object"){ ws.send(JSON.stringify({"type":"say","lid":data.lid,"content":data.content,"shstatus":data.shstatus,"msgtype":data.msgtype,"roleid":roleid,"rolename":rolename,"roleaid":roleaid})); notice("红包已发送"); $('.bar_redbag span').html('¥'+data.yue); $("#rendbag_num").val(''); $('#rendbag_total').val(''); $.fancybox.close(); }else if(data=="invalidate_num"){ notice("单个红包金额最少为1"); }else{ notice("对不起,您的账户余额不足"); $("#redbag_pay_btn").click(); } } }); } function getRedbag(e){ var redbag=$(e).attr('rel'); $.ajax({ url: "action.php?type=getredbag", type: "POST", async: true, data:{redbag:redbag}, dataType: "json", error: function(){ }, success: function(data){//如果调用php成功 if(typeof(data) == "object"){ alert("恭喜你,领取了红包¥"+data.count); ws.send(JSON.stringify( {"type":"getredbag","sh_content":data.content} ) ); $('.bar_redbag span').html('¥'+data.yue); getRedbagInfo(redbag) }else if(data=="invalidateadminid"){ notice("请登录之后再抢红包"); $("#fancybox-inner").show(); getRedbagInfo(redbag) }else if(data=="hasgot"){ notice("您已经领过改红包领了,请下次再领吧"); getRedbagInfo(redbag) }else{ notice("红包领取完了,请下次再领吧"); getRedbagInfo(redbag) } } }); } function getRedbagInfo(redbag){ $.ajax({ url: "action.php?type=getredbaginfo", type: "POST", async: true, data:{redbag:redbag}, dataType: "json", error: function(){ }, success: function(data){ if(typeof(data) == "object"){ var redbag=data.redbag; var get_list=data.get_list; $("#redbag_info ._avatar").html('<img src="/images/level/User'+redbag.adminid+'.png"/>'); $("#redbag_info h1").html("已领取"+get_list.length+"/"+redbag.num+"个"); $("#redbag_info ._info ._info_total").html('共 ¥'+redbag.total); $("#redbag_info ._info ._info_from").html('来自 '+redbag.username); $("#redbag_info table").html('') for(i in get_list){ var d=new Date(parseInt(get_list[i].time)*1000); var shijian=formatDate(d); var tr_str='<tr> <td style="width:15%"><img src="/images/level/User'+get_list[i].adminid+'.png"></td><td><span>'+get_list[i].username+'</span><p>'+shijian+'</p></td> <td style="width:30%">¥'+get_list[i].count+'</td> </tr>'; $("#redbag_info table").append(tr_str) } $("#redbag_info_btn").click(); } } }); }
长连接、短连接与WebSocket 的区别_网络_xiaomajia029的博客-CSDN博客 https://blog.csdn.net/xiaomajia029/article/details/79748528
TCP(HTTP)长连接和短连接区别和怎样维护长连接_网络_jayxu无捷之径的博客-CSDN博客 https://blog.csdn.net/ls5718/article/details/51757467
WebSocket - 廖雪峰的官方网站 https://www.liaoxuefeng.com/wiki/1022910821149312/1103303693824096
WebSocket是HTML5新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道,比如说,服务器可以在任意时刻发送消息给浏览器。
为什么传统的HTTP协议不能做到WebSocket实现的功能?这是因为HTTP协议是一个请求-响应协议,请求必须先由浏览器发给服务器,服务器才能响应这个请求,再把数据发送给浏览器。换句话说,浏览器不主动请求,服务器是没法主动发数据给浏览器的。
这样一来,要在浏览器中搞一个实时聊天,在线炒股(不鼓励),或者在线多人游戏的话就没法实现了,只能借助Flash这些插件。
也有人说,HTTP协议其实也能实现啊,比如用轮询或者Comet。轮询是指浏览器通过JavaScript启动一个定时器,然后以固定的间隔给服务器发请求,询问服务器有没有新消息。这个机制的缺点一是实时性不够,二是频繁的请求会给服务器带来极大的压力。
Comet本质上也是轮询,但是在没有消息的情况下,服务器先拖一段时间,等到有消息了再回复。这个机制暂时地解决了实时性问题,但是它带来了新的问题:以多线程模式运行的服务器会让大部分线程大部分时间都处于挂起状态,极大地浪费服务器资源。另外,一个HTTP连接在长时间没有数据传输的情况下,链路上的任何一个网关都可能关闭这个连接,而网关是我们不可控的,这就要求Comet连接必须定期发一些ping数据表示连接“正常工作”。
以上两种机制都治标不治本,所以,HTML5推出了WebSocket标准,让浏览器和服务器之间可以建立无限制的全双工通信,任何一方都可以主动发消息给对方。
WebSocket协议
WebSocket并不是全新的协议,而是利用了HTTP协议来建立连接。我们来看看WebSocket连接是如何创建的。
首先,WebSocket连接必须由浏览器发起,因为请求协议是一个标准的HTTP请求,格式如下:
GET ws://localhost:3000/ws/chat HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Origin: http://localhost:3000
Sec-WebSocket-Key: client-random-string
Sec-WebSocket-Version: 13
该请求和普通的HTTP请求有几点不同:
- GET请求的地址不是类似
/path/
,而是以ws://
开头的地址; - 请求头
Upgrade: websocket
和Connection: Upgrade
表示这个连接将要被转换为WebSocket连接; Sec-WebSocket-Key
是用于标识这个连接,并非用于加密数据;Sec-WebSocket-Version
指定了WebSocket的协议版本。
随后,服务器如果接受该请求,就会返回如下响应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: server-random-string
该响应代码101
表示本次连接的HTTP协议即将被更改,更改后的协议就是Upgrade: websocket
指定的WebSocket协议。
版本号和子协议规定了双方能理解的数据格式,以及是否支持压缩等等。如果仅使用WebSocket的API,就不需要关心这些。
现在,一个WebSocket连接就建立成功,浏览器和服务器就可以随时主动发送消息给对方。消息有两种,一种是文本,一种是二进制数据。通常,我们可以发送JSON格式的文本,这样,在浏览器处理起来就十分容易。
为什么WebSocket连接可以实现全双工通信而HTTP连接不行呢?实际上HTTP协议是建立在TCP协议之上的,TCP协议本身就实现了全双工通信,但是HTTP协议的请求-应答机制限制了全双工通信。WebSocket连接建立以后,其实只是简单规定了一下:接下来,咱们通信就不使用HTTP协议了,直接互相发数据吧。
安全的WebSocket连接机制和HTTPS类似。首先,浏览器用wss://xxx
创建WebSocket连接时,会先通过HTTPS创建安全的连接,然后,该HTTPS连接升级为WebSocket连接,底层通信走的仍然是安全的SSL/TLS协议。