小结:

1、

一个HTTP连接在长时间没有数据传输的情况下,链路上的任何一个网关都可能关闭这个连接,而网关是我们不可控的

websocket

http://kai.yilaizhibo.com/js/controller.js http://kai.yilaizhibo.com/js/controller.js

  1. $(function(){
  2.  
  3. init();
  4. $(document).on("dblclick",".liaotian_right div",function(){
  5. $.fancybox($(this).html().replace("max-width:500px; max-height:600px",""), {
  6. scrolling: "no",
  7. padding: 20,
  8. transitionIn: "none",
  9. transitionOut: "none"
  10. });
  11. });
  12. var $_GET = (function(){
  13. var url = window.document.location.href.toString();
  14. var u = url.split("?");
  15. if(typeof(u[1]) == "string"){
  16. u = u[1].split("&");
  17. var get = {};
  18. for(var i in u){
  19. var j = u[i].split("=");
  20. get[j[0]] = j[1];
  21. }
  22. return get;
  23. } else {
  24. return {};
  25. }
  26. })();
  27. if(ADMINID==14){
  28.  
  29. if(VIEWSTATUS!='0'){
  30. setTimeout('clearVideo()',60*VIEWTIME*1000);
  31. }}
  32. $(".zaixian_tit a").click(function(){
  33. $(".zaixian_tit a").removeClass("on");
  34. $(this).addClass("on");
  35.  
  36. if($.trim($("#user_select.on").text())=="我的客户"){
  37. $('#users_online li').each(function(){
  38. if($(this).attr('tuijianmid')!=MID){
  39. $(this).hide();
  40. }
  41. });
  42. }else if($.trim($("#user_select.on").text())=="我的客服"){
  43. $('#users_online li').each(function(){
  44. if($(this).attr('uid')!=TUIJIANMID){
  45. $(this).hide();
  46. }
  47. });
  48. }else{
  49. $('#users_online').show();
  50. // $('#mykefu').hide();
  51. $('#users_online li').show();
  52. }
  53. });
  54. $("#liaotianlist").scroll( function() {
  55. var viewH =$(this).height();
  56. var contentH =$(this).scrollHeight;//内容高度
  57. var scrollTop =$(this).scrollTop();
  58. if(viewH>=scrollTop){
  59. $(".load_more").show('fast')
  60. }else{
  61. $(".load_more").hide('fast')
  62. }
  63. } );
  64.  
  65. $("#role_select").change(function(){
  66.  
  67. var _aid=$("#role_select>option[value='"+$(this).val()+"']").attr("aid");
  68.  
  69. if(_aid=='1'){
  70. $('.bar_quanping[id=gundong]').show();
  71. }else {
  72. $('.bar_quanping[id=gundong]').hide();
  73. }
  74. });
  75.  
  76. });
  77. function formatDate(now) {
  78.  
  79. var year=now.getYear();
  80. var month=now.getMonth()+1;
  81. var date=now.getDate();
  82. var hour=now.getHours();
  83. var minute=now.getMinutes();
  84. var second=now.getSeconds();
  85. if(hour<10){
  86. hour='0'+hour;
  87. }
  88. if(minute<10){
  89. minute='0'+minute;
  90. }
  91. if(second<10){
  92. second='0'+second;
  93. }
  94. return hour+":"+minute;
  95. }
  96. function init() {
  97. ws = new WebSocket("ws://"+WS_HOST+":"+WS_PORT);
  98. // 创建websocket
  99. // 当socket连接打开时,输入用户名
  100. ws.onopen = function() {
  101. timeid && window.clearInterval(timeid);
  102.  
  103. if(!USERNAME) {
  104. window.location.reload();
  105. return ws.close();
  106. }
  107. if(reconnect == false)
  108. {
  109. // 登录
  110.  
  111. 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});
  112. // console.log("websocket握手成功,发送登录数据:"+login_data);
  113. ws.send(login_data);
  114.  
  115. reconnect = true;
  116. }
  117. else
  118. {
  119. // 断线重连
  120. 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});
  121. console.log("websocket握手成功,发送重连数据:"+relogin_data);
  122. ws.send(relogin_data);
  123. }
  124. };
  125. // 当有消息时根据消息类型显示不同信息
  126. ws.onmessage = function(e) {
  127.  
  128. //console.log(e);
  129. var data = JSON.parse(e.data);
  130. //console.log(e);
  131. switch(data.type){
  132. // 服务端ping客户端
  133. case 'ping':
  134. ws.send(JSON.stringify({"type":"pong"}));
  135. break;;
  136. // 登录 更新用户列表
  137. case 'login':
  138. if(ADMINID==1 && LOGIN_TIP==1){
  139. $('#liaotianlist').append( '<div class="liaotian"> <div class="liaotian_right fl"><div>'+ data.client_name+'大步来到赛场!</div></div></div>' );
  140. }
  141. if($("#liaotianlist .liaotian").length>30){
  142. $("#liaotianlist .liaotian:lt(1)").remove();
  143. }
  144. if($('.bar_gundong').attr('checked')){
  145. $('#liaotianlist').animate( { scrollTop: $('#liaotianlist')[0].scrollHeight } ,1000 );
  146. }
  147. // 登录请求是自己发的 就全量。 是别人发的 就增量
  148. if( data.client_name == USERNAME){
  149. flush_client_list(data.client_list);
  150. }else{
  151. flush_client_list_add(data.client_item);
  152. }
  153. break;
  154. // 断线重连,只更新用户列表
  155. case 're_login':
  156. flush_client_list(data.client_list);
  157. console.log(data['client_name']+"重连成功");
  158. break;
  159. // 登录出错
  160. /*case 'login_error':
  161. alert('对不起,系统检测您的账号已处于登录状态');
  162. window.location.href='/sys/off.php';
  163. break;*/
  164. // 发言
  165. case 'say':
  166. //{"type":"say","from_client_id":xxx,"to_client_id":"all/client_id","content":"xxx","time":"xxx"}
  167. say(data);
  168. break;
  169. // 私聊
  170. case 'siliao': //{"type":"say","from_client_id":xxx,"to_client_id":"all/client_id","content":"xxx","time":"xxx"}
  171. siliao(data);
  172. break;
  173. // 通知直播间中iframe 切换主播
  174. case 'switchAnchor':
  175. if($("#video-win").length>0 && data.uid){
  176. $('#video-win iframe').contents().find('iframe').attr('src', 'http://www.zhiniu8.com/h5live?uid='+data.uid);
  177. }
  178. break;
  179. case 'pubclear':
  180. $('#liaotianlist').html('');
  181. break;
  182. case 'tuijian':
  183. if(ADMINID==14 && TUIJIANMID!=data.mid && data.mid){
  184. TUIJIANMID=data.mid;
  185. $.get("action.php?type=changetuijian",{mid:data.mid},function(data,status){});
  186. }
  187. break;
  188. case 'deleteliaotian':
  189. $("#"+data.lid).remove();
  190. break;
  191. case 'logout':
  192. if(ADMINID==1 && LOGIN_TIP==1){
  193. $('#liaotianlist').append( '<div class="liaotian"> <div class="liaotian_right fl"><div>'+data['from_client_name']+'怀揣着炒股秘籍,依依不舍的离开了!</div></div></div>' );
  194. }
  195. $("#users_online li").each(function(){
  196. if ( $(this).attr('uid') ==data.mid) {
  197. $(this).remove();
  198. return false;
  199. }
  200. });
  201. // console.log(data.client_list);
  202. flush_client_list(data.client_list);
  203. $(".renshu b").html(parseInt($(".renshu").attr('rel'))+parseInt($("#users_online li").length));
  204. $(".renshu sj span").html(parseInt($("#users_online li").length))
  205.  
  206. }
  207. };
  208. ws.onclose = function() {
  209.  
  210. console.log("连接关闭,定时重连");
  211. // 定时重连
  212.  
  213. window.clearInterval(timeid);
  214. timeid = window.setInterval(init, 3000);
  215. };
  216. ws.onerror = function() {
  217. // alert("出现错误");
  218. window.setTimeout(init, 3000);
  219. };
  220. }
  221. function clearVideo(){
  222. video_html = '<p>对不起,您的观看时间已到,请联系客服后继续观看</p>';
  223. $(".shipinchuangkou").html(video_html);
  224. $.cookie('clearvideo',true,{expires:1});
  225. }
  226.  
  227. function switchAnchor(jid){
  228. ws. send(JSON.stringify({"type":"switchAnchor","uid":jid}));//socket发送 uid 切换直播iframe url
  229. }
  230.  
  231. function addliaotian(siliao){
  232. WAIT=FAYAN_LIMIT;
  233. var tomid,tousername;
  234. if(ADMINID==14 && WAIT>0 && WAIT!=FAYAN_LIMIT){
  235. $("#ts").click();
  236. return false;
  237. }
  238.  
  239. if(ADMINID!=1 && ADMINID!=2){
  240. var content=$('#send_input').val();
  241. $('#send_input').val('');
  242. }else{
  243. var content=UE.getEditor('send_input').getContent();
  244. UE.getEditor('send_input').setContent('');
  245. }
  246.  
  247. tomid=TOMID;
  248. tousername=TOUSERNAME;
  249. if(siliao===1){
  250. content=$('#Y_iSend_Input2').text();
  251. $('#Y_iSend_Input2').html('');
  252. }else{
  253. tomid=$('#send_talkto').val();
  254. tousesrname=$('#send_talkto').attr('uname');
  255. siliao=0;
  256. }
  257. var quanping=$('.bar_quanping').attr('checked')?1:0;
  258. if(!content){
  259. return false;
  260. }
  261. var roleid=$("#role_select option:selected").attr('uid');
  262. var rolename=$("#role_select").val();
  263. var roleaid=$("#role_select option:selected").attr('aid');
  264. $.ajax({
  265. url: "action.php?type=addliaotian",
  266. type: "POST",
  267. async: true,
  268. data:{content:content,username:USERNAME,mid:MID,tomid:tomid,tousername:tousername,siliao:siliao,roleid:roleid,rolename:rolename,roleaid:roleaid},
  269. dataType: "json",
  270. error: function(){
  271. // alert('Error loading XML document');
  272. },
  273.  
  274. success: function(data){//如果调用php成功
  275.  
  276. if(data.content){
  277. console.log(siliao);
  278. if(siliao===1){
  279. ws.send(JSON.stringify({"type":"siliao","tomid":data.tomid,"tousername":data.tousername,"toadminid":data.toadminid,"content":data.content}));
  280. }else{
  281. if(quanping){
  282. data.quanping=1;
  283. }
  284. say(data);
  285. 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发送公聊信息
  286. }
  287.  
  288. }else if(data=='iphei'){
  289. window.location.reload();
  290. }else if(data=='shenhe'){
  291. notice('消息审核中。。。');
  292. }else if(!isNaN(data)){
  293. WAIT=data;
  294. $("#ts").click();
  295.  
  296. }else if(data=='jinyan'){
  297. notice('对不起,您所在的用户组不允许发言');
  298. }
  299.  
  300. }
  301. });
  302.  
  303. if(!limitCount){
  304. limitCount= setInterval(fayanLimit,1000);
  305. }
  306.  
  307. }
  308.  
  309. // 新增用户到 用户列表
  310. function flush_client_list_add(client)
  311. {
  312. var v = client;
  313. if($("#users_online li[uid='"+v['mid']+"']").length>0){
  314. $("#users_online li[uid='"+v['mid']+"'] .u_l").html('('+v['login_count']+')');
  315. return true;
  316. }
  317. var hasInsert=0;
  318. var user_pingbi='';
  319. var userhide='';
  320.  
  321. if(ADMINID==3 && $.trim($("#user_select.on").text())=="我的客户" && v['tuijianmid']!=MID){
  322. var userhide='style="display:none"';
  323. }
  324. if(ADMINID=='1'){
  325. var u_l='<span class="u_l">('+v['login_count']+')</span>';
  326. 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>';
  327. }else if(ADMINID=='2'){
  328. var u_l='';
  329. 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>';
  330. }else if(ADMINID=='3'){
  331. var u_l='<span class="u_l">('+v['login_count']+')</span>';
  332. 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>';
  333. }else{
  334. var u_l='';
  335. var ban_str='';
  336. }
  337.  
  338. 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="data:images/level/vip'+v['adminid']+'.png"></span> <p><a href="javascript:void(0)" class="talkto" onclick="sayTo(this)">对TA说</a>'+ban_str+'</p></li>';
  339. if($("#users_online li").length>0){
  340.  
  341. $("#users_online li").each(function(){
  342.  
  343. if(parseInt($(this).attr('adminid'))> parseInt(v['adminid'])){
  344. $(this).before(str);
  345. hasInsert=1;//标记是否插入数据
  346. return false;
  347. }
  348. });
  349. }
  350.  
  351. if(!hasInsert){
  352.  
  353. $("#users_online").append(str);
  354. }
  355.  
  356. $(".renshu b").html(parseInt($(".renshu").attr('rel'))+parseInt($("#users_online li").length));
  357. $(".renshu sj span").html(parseInt($("#users_online li").length))
  358. }
  359.  
  360. // 刷新用户列表框
  361. function flush_client_list(client_list){
  362. if ( !client_list ) {
  363. return false;
  364. }
  365. $.each( client_list, function( k, v ){
  366.  
  367. if($("#users_online li[uid='"+v['mid']+"']").length>0){
  368. $("#users_online li[uid='"+v['mid']+"'] .u_l").html('('+v['login_count']+')');
  369. return true;
  370. }
  371. var hasInsert=0;
  372. var user_pingbi='';
  373. var userhide='';
  374.  
  375. if(ADMINID==3 && $.trim($("#user_select.on").text())=="我的客户" && v['tuijianmid']!=MID){
  376. var userhide='style="display:none"';
  377. }
  378. if(ADMINID=='1'){
  379. var u_l='<span class="u_l">('+v['login_count']+')</span>';
  380. 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>';
  381. }else if(ADMINID=='2'){
  382. var u_l='';
  383. 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>';
  384. }else if(ADMINID=='3'){
  385. var u_l='<span class="u_l">('+v['login_count']+')</span>';
  386. 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>';
  387. }else{
  388. var u_l='';
  389. var ban_str='';
  390. }
  391.  
  392. 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="data:images/level/vip'+v['adminid']+'.png"></span> <p><a href="javascript:void(0)" class="talkto" onclick="sayTo(this)">对TA说</a>'+ban_str+'</p></li>';
  393. if($("#users_online li").length>0){
  394.  
  395. $("#users_online li").each(function(){
  396.  
  397. if(parseInt($(this).attr('adminid'))> parseInt(v['adminid'])){
  398. $(this).before(str);
  399. hasInsert=1;//标记是否插入数据
  400. return false;
  401. }
  402. });
  403. }
  404.  
  405. if(!hasInsert){
  406.  
  407. $("#users_online").append(str);
  408. }
  409.  
  410. });
  411. $(".renshu b").html(parseInt($(".renshu").attr('rel'))+parseInt($("#users_online li").length));
  412. $(".renshu sj span").html(parseInt($("#users_online li").length))
  413. }
  414.  
  415. // 发言
  416. function say(data){
  417.  
  418. // console.info(data);
  419.  
  420. var t = $('#liaotianlist');
  421.  
  422. var d=new Date(parseInt(data.time)*1000);
  423. var shijian=formatDate(d);
  424. var sh_str='';
  425.  
  426. if((ADMINID==3 || ADMINID==1) && data.shstatus=="0"){
  427. sh_str='<a href="javascript:void(0)" rel="'+data.lid+'" onclick="liaotianShenhe(this)" class="lt_sh">审核</a>'
  428. }
  429. if(ADMINID==3 || ADMINID==1){
  430. 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>'
  431. }
  432. if((ADMINID==3 || ADMINID==1) && data.shstatus=="1"){
  433.  
  434. if($(".lt_sh[rel='"+data.lid+"']").length>0){
  435. $(".lt_sh[rel='"+data.lid+"']").remove();
  436. return false;
  437. }
  438. }
  439.  
  440. if(!(ADMINID==3 || ADMINID==1) && data.shstatus=="0"){
  441.  
  442. return false;
  443. }
  444. if($(".liaotian[id='"+data.lid+"']").length>0 && data.lid){
  445. return false;
  446. }
  447. if( data.username!='交易提示' && data.username!='系统提示'){
  448. if(data.tomid && data.tomid!="null" && data.tomid!="undefined" && data.tomid!="0"){
  449.  
  450. To_str='<a class="user_to">对</a><img src="data:images/level/User'+data.toadminid+'.png"/><a href="javascript:void)(0)" uid="'+data.tomid+'" uname="'+data.tousername+'" onclick="User_Click(this)">'+data.tousername+'</a>';
  451.  
  452. }else{
  453. var To_str='';
  454. }
  455. var redbagdiv='';
  456. if(data.msgtype==2){
  457. play('mp3/5103.mp3');
  458. redbagdiv="redbagdiv";
  459. }
  460.  
  461. 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="data: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>';
  462.  
  463. }else{
  464.  
  465. if(data.username=='交易提示'){
  466. play('mp3/5103.mp3');
  467. var click_str='onclick="$(\'#hdtx\').click()"';
  468. 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>';
  469. }else{
  470. var str ='<div class="liaotian "> <div class="liaotian_right fl m3"> <div >'+data.content+'</div></div> </div>';
  471. }
  472. }
  473. t.append(str);
  474. if($("#liaotianlist .liaotian").length>30){
  475. $("#liaotianlist .liaotian:lt(1)").remove();
  476. }
  477. if($('.bar_gundong').attr('checked')){
  478. t.animate( { scrollTop: t[0].scrollHeight } ,1000 );
  479. }
  480. if(data.quanping){
  481. $('.quanping').append('<div>'+data.content.replace(/<[^>]+>/g,"")+'</div>');
  482. init_screen()
  483. }
  484. }
  485.  
  486. function siliao(data){
  487. $(".loading").hide()
  488. var t = $('#liaotianlist');
  489.  
  490. tomid=TOMID;
  491. tousername=TOUSERNAME;
  492.  
  493. var d=new Date(parseInt(data.time)*1000);
  494. var shijian=formatDate(d);
  495.  
  496. if(data.mid==tomid || data.tomid==tomid ){
  497.  
  498. var str=' <div class="liaotian"> <div class="liaotian_left fl"><img src="data: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>';
  499.  
  500. $("#Y_PriMes_Div ").append(str);
  501.  
  502. }else{
  503.  
  504. var uid= (MID==data.tomid)?data.mid: data.tomid;
  505. var uname= (USERNAME==data.tousername)?data.username:data.tousername;
  506. var hassiliao=$(".l-tab-links ul li[uid='"+uid+"']");
  507. if(hassiliao.length==0){
  508. if($(".l-tab-links ul li").length==0){//no body
  509.  
  510. TOMID=uid;
  511. TOUSERNAME=uname;
  512. // sayTo();
  513. 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>';
  514. var c_str=' <div class="liaotian"> <div class="liaotian_left fl"><img src="data: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>';
  515.  
  516. $("#Y_PriMes_Div ").append(c_str);
  517.  
  518. }else{
  519. 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>';
  520.  
  521. }
  522. $(".l-tab-links ul").append(str);
  523.  
  524. }else{
  525.  
  526. hassiliao.find('a').css("color","red");
  527. }
  528. }
  529. if($(".whisper").is(":hidden")) {
  530. $(".whisper").show();
  531.  
  532. }
  533. if($("#Y_PriMes_Div .liaotian").length>30){
  534. $("#Y_PriMes_Div .liaotian:lt(1)").remove();
  535. }
  536. $("#Y_PriMes_Div ").animate( { scrollTop: $("#Y_PriMes_Div ")[0].scrollHeight } ,100 );
  537.  
  538. }
  539.  
  540. function fayanLimit(){
  541.  
  542. $('.tishi_content t').html(WAIT);
  543. WAIT--;
  544. if(WAIT==0){
  545. clearInterval(limitCount);
  546. limitCount='';
  547. $.fancybox.close();
  548. WAIT=FAYAN_LIMIT;
  549. }
  550.  
  551. }
  552.  
  553. function notice(content){
  554. $("#qtip-growl-container").qtip({
  555. content: {text: content,title: "提示" },
  556. corner: {
  557. target: 'bottomRight',
  558. tooltip: 'topLeft'
  559. },
  560. style: { classes: 'qtip-dark qtip-shadow qtip-rounded' },
  561. show: {
  562. ready:true ,
  563. effect: function() {
  564. $(this).slideDown();
  565. }
  566. },
  567. hide: {
  568. event: false,
  569. inactive: 5000,
  570. effect: function() {
  571. $(this).slideUp();
  572. }
  573. }
  574. });
  575. }
  576.  
  577. function getSiliaodata(){
  578. var tomid=TOMID;
  579. var tousername=TOUSERNAME;
  580. $.ajax({
  581. url: "action.php?type=getSiliaodata",
  582. type: "POST",
  583. data:{mid:MID,tomid:tomid},
  584. timeout:8000,
  585. dataType: "json",
  586. cache:false,
  587. success: function(msg){//msg为返回的数据,在这里做数据绑定
  588. $(".loading").hide();
  589. $('#Y_PriMes_Div .liaotian').remove();
  590. if(msg instanceof Array){
  591. for(i in msg){
  592.  
  593. siliao(msg[i]);
  594. }
  595. }
  596.  
  597. },
  598. error:function(XMLHttpRequest,textStatus,errorThrown){
  599. }
  600.  
  601. });
  602.  
  603. }
  604.  
  605. function pingbi(t){
  606. if(!window.confirm("确认屏蔽此人?"))
  607. {
  608. return false;
  609. }
  610. if(ADMINID<=3){
  611. $.ajax({
  612. url: "action.php?type=pingbi",
  613. type: "POST",
  614. async: true,
  615. data:{mid:TOMID,t:t},
  616. //dataType: "json",
  617. error: function(){
  618. // alert('Error loading XML document');
  619. },
  620. success: function(data){//如果调用php成功
  621. if(data=="true"){
  622. notice("屏蔽成功");
  623. }else{
  624. notice("屏蔽失败");
  625. }
  626. }
  627. });
  628. }else{
  629. notice('您不具有此权限');
  630. }
  631. }
  632.  
  633. function ipban(){
  634. if(!window.confirm("确认封掉此人IP?"))
  635. {
  636. return false;
  637. }
  638. if(ADMINID<=3){
  639. $.ajax({
  640. url: "action.php?type=ipban",
  641. type: "POST",
  642. async: true,
  643. data:{mid:TOMID},
  644. //dataType: "json",
  645. error: function(){
  646. // alert('Error loading XML document');
  647. },
  648. success: function(data){//如果调用php成功
  649. if(data=="true"){
  650. notice("屏蔽成功");
  651. }else{
  652. notice("屏蔽失败");
  653. }
  654. }
  655. });
  656. }else{
  657. notice('您不具有此权限');
  658. }
  659. }
  660.  
  661. function liaotianShenhe(e){
  662. $.ajax({
  663. url: "action.php?type=updateliaotian",
  664. type: "POST",
  665. data:{lid:e.rel},
  666. timeout:8000,
  667. dataType: "json",
  668. cache:false,
  669. success: function(msg){//msg为返回的数据,在这里做数据绑定
  670. if(typeof(msg) == "object"){
  671. var lid=msg.lid;
  672. var sh_mid=msg.mid;
  673. var username=msg.username;
  674. var adminid=msg.adminid;
  675.  
  676. var sh_tomid=msg.tomid;
  677. var tousername=msg.tousername;
  678. var toadminid=msg.toadminid;
  679. var sh_content=msg.content;
  680. 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 } ) );
  681.  
  682. $(e).remove();
  683. }else if(msg=='yishenhe'){
  684. $(e).remove();
  685. }else{
  686. notice('操作失败');
  687. }
  688. },
  689. error:function(XMLHttpRequest,textStatus,errorThrown){
  690. }
  691.  
  692. });
  693. }
  694.  
  695. function liaotianDel(e){
  696. $.ajax({
  697. url: "action.php?type=deleteliaotian",
  698. type: "POST",
  699. data:{lid:e.rel},
  700. timeout:8000,
  701. dataType: "json",
  702. cache:false,
  703. success: function(msg){//msg为返回的数据,在这里做数据绑定
  704. if(typeof(msg) == "object"){
  705. var lid=msg.lid;
  706. ws.send(JSON.stringify( {"type":"deleteliaotian","lid":lid,"fid":FID } ) );
  707. $("#"+lid).remove();
  708. }else{
  709. notice('操作失败');
  710. }
  711. },
  712. error:function(XMLHttpRequest,textStatus,errorThrown){
  713. }
  714.  
  715. });
  716. }
  717.  
  718. function SendFlower(jid){
  719.  
  720. if(!Flower_NUM){
  721. notice('对不起,您没有足够的红包');
  722. return false;
  723. }
  724. var _jr_name=$('#role_select').val();
  725. $.ajax({
  726. url: "action.php?type=sendflower",
  727. type: "POST",
  728. async: true,
  729. data:{jid:jid,jiaren:_jr_name},
  730. dataType: "json",
  731. error: function(){
  732. // alert('Error loading XML document');
  733. },
  734. success: function(data){//如果调用php成功
  735. if(data!="false"){
  736. notice("送花成功");
  737. $('.FlowerNum span').html(data.num);
  738. Flower_NUM--;
  739. $(".bar_flower span").html(Flower_NUM);
  740.  
  741. ws.send(JSON.stringify( {"type":"sendflower","sh_content":data.content} ) );
  742.  
  743. }else{
  744. notice("您已经没有花了");
  745. }
  746. }
  747. });
  748. }
  749.  
  750. function GetFlower(){
  751. $.get("action.php?type=getflower",function(data,status){
  752. if(!isNaN(data)){
  753. Flower_NUM=data;
  754. }else{
  755. setTimeout("GetFlower",1000);
  756. }
  757. });
  758. }
  759.  
  760. function addFlower(){
  761. Flower_NUM++;
  762. $(".bar_flower span").html(Flower_NUM);
  763. $.get("action.php?type=addflower&mid="+MID,function(data,status){});
  764. }
  765.  
  766. function setTeacherId(mid){
  767. $.get("action.php?type=setteacherid&mid="+mid,function(data,status){
  768. if(!isNaN(data)){
  769. $('.RegBagNum span').html(data);
  770. }
  771. });
  772. }
  773.  
  774. function loadMore(){
  775. var load_more=$(".load_more");
  776. $(".load_more a").addClass('wait');
  777. $(".load_more a").text('');
  778. var lid=$("#liaotianlist .liaotian[id!='']:first").attr('id');
  779.  
  780. $.get("action.php?type=loadmore&lid="+lid,function(msg,status){
  781. if(msg!='false'){
  782. for(i in msg){
  783. data=msg[i];
  784. if(data.tomid && data.tomid!="null" && data.tomid!="undefined" && data.tomid!="0"){
  785. var To_str='<a class="user_to">对</a><img src="data:images/level/User'+data.toadminid+'.png"/><a href="javascript:void)(0)" uid="'+data.tomid+'" uname="'+data.tousername+'" onclick="User_Click(this)">'+data.tousername+'</a>';
  786. }else{
  787. var To_str='';
  788. }
  789. var d=new Date(parseInt(data.time)*1000);
  790. var shijian=formatDate(d);
  791. var redbagdiv=data.msgtype==2?'redbagdiv':'';
  792. 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="data: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>';
  793. $('#liaotianlist').prepend(str);
  794. }
  795. $(".load_more a").removeClass('wait');
  796. $(".load_more a").text('查看更多信息');
  797. $('#liaotianlist').prepend(load_more);
  798. $('#liaotianlist').scrollTop($("#liaotianlist .liaotian[id='"+lid+"']").offset().top);
  799.  
  800. }else{
  801. //alert('加载失败');
  802. }
  803. },'json');
  804. }
  805. function loadykmore(){
  806. var uid=$("#users_online li[uid!='']:last").attr('uid');
  807. $.get("action.php?type=loadykmore&uid="+uid,function(msg,status){
  808. if(msg!='false'){
  809. for(i in msg){
  810. data=msg[i];
  811. var d=new Date(parseInt(data.time)*1000);
  812. var shijian=formatDate(d);
  813. var redbagdiv=data.msgtype==2?'redbagdiv':'';
  814. 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="data:images/level/vip'+data.adminid+'.png" ></span><p><a href="javascript:void(0)" class="talkto" onclick="sayTo()">对TA说</a></p></li>';
  815. $('#users_online').append(str);
  816. }
  817. $(".loadykmore a").removeClass('wait');
  818. $(".loadykmore a").text('查看更多信息');
  819. }else{
  820. // alert('加载失败');
  821. }
  822. },'json');
  823. }
  824. function changeSkin(e){
  825. $('#skin img').attr('src',e.rel);
  826. $.cookie('bg_img',e.rel, {expires: 365, path: '/'});
  827. $("#skin img").attr("src",e.rel);
  828. }
  829.  
  830. function getUserInfo(e){
  831. $.get("action.php?type=getuserinfo&mid="+e.rel,function(data,status){
  832. if(data){
  833. $(e).html('Dzip:'+data.dzip+',IP:'+data.ip+',注册时间:'+data.regtime+',备注:'+data.beizhu);
  834. }
  835. },'json');
  836. }
  837.  
  838. function sendRedbag(){
  839. var _num=$("#rendbag_num").val();
  840. var _total=$('#rendbag_total').val();
  841. var roleid=$("#role_select option:selected").attr('uid');
  842. var rolename=$("#role_select").val();
  843. var roleaid=$("#role_select option:selected").attr('aid');
  844. $.ajax({
  845. url: "action.php?type=sendredbag",
  846. type: "POST",
  847. async: true,
  848. data:{num:_num,total:_total},
  849. dataType: "json",
  850. error: function(){
  851. },
  852. success: function(data){//如果调用php成功
  853. if(typeof(data) == "object"){
  854.  
  855. ws.send(JSON.stringify({"type":"say","lid":data.lid,"content":data.content,"shstatus":data.shstatus,"msgtype":data.msgtype,"roleid":roleid,"rolename":rolename,"roleaid":roleaid}));
  856. notice("红包已发送");
  857.  
  858. $('.bar_redbag span').html('¥'+data.yue);
  859. $("#rendbag_num").val('');
  860. $('#rendbag_total').val('');
  861. $.fancybox.close();
  862. }else if(data=="invalidate_num"){
  863. notice("单个红包金额最少为1");
  864. }else{
  865. notice("对不起,您的账户余额不足");
  866. $("#redbag_pay_btn").click();
  867. }
  868. }
  869. });
  870. }
  871.  
  872. function getRedbag(e){
  873. var redbag=$(e).attr('rel');
  874. $.ajax({
  875. url: "action.php?type=getredbag",
  876. type: "POST",
  877. async: true,
  878. data:{redbag:redbag},
  879. dataType: "json",
  880. error: function(){
  881. },
  882. success: function(data){//如果调用php成功
  883. if(typeof(data) == "object"){
  884. alert("恭喜你,领取了红包¥"+data.count);
  885. ws.send(JSON.stringify( {"type":"getredbag","sh_content":data.content} ) );
  886. $('.bar_redbag span').html('¥'+data.yue);
  887. getRedbagInfo(redbag)
  888. }else if(data=="invalidateadminid"){
  889. notice("请登录之后再抢红包");
  890. $("#fancybox-inner").show();
  891. getRedbagInfo(redbag)
  892. }else if(data=="hasgot"){
  893. notice("您已经领过改红包领了,请下次再领吧");
  894. getRedbagInfo(redbag)
  895. }else{
  896. notice("红包领取完了,请下次再领吧");
  897. getRedbagInfo(redbag)
  898. }
  899. }
  900. });
  901. }
  902.  
  903. function getRedbagInfo(redbag){
  904. $.ajax({
  905. url: "action.php?type=getredbaginfo",
  906. type: "POST",
  907. async: true,
  908. data:{redbag:redbag},
  909. dataType: "json",
  910. error: function(){ },
  911.  
  912. success: function(data){
  913. if(typeof(data) == "object"){
  914. var redbag=data.redbag;
  915. var get_list=data.get_list;
  916. $("#redbag_info ._avatar").html('<img src="/images/level/User'+redbag.adminid+'.png"/>');
  917. $("#redbag_info h1").html("已领取"+get_list.length+"/"+redbag.num+"个");
  918. $("#redbag_info ._info ._info_total").html('共 ¥'+redbag.total);
  919. $("#redbag_info ._info ._info_from").html('来自 '+redbag.username);
  920. $("#redbag_info table").html('')
  921. for(i in get_list){
  922. var d=new Date(parseInt(get_list[i].time)*1000);
  923. var shijian=formatDate(d);
  924. 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>';
  925. $("#redbag_info table").append(tr_str)
  926. }
  927. $("#redbag_info_btn").click();
  928. }
  929. }
  930. });
  931.  
  932. }

  

长连接、短连接与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请求,格式如下:

  1. GET ws://localhost:3000/ws/chat HTTP/1.1
  2. Host: localhost
  3. Upgrade: websocket
  4. Connection: Upgrade
  5. Origin: http://localhost:3000
  6. Sec-WebSocket-Key: client-random-string
  7. Sec-WebSocket-Version: 13

该请求和普通的HTTP请求有几点不同:

  1. GET请求的地址不是类似/path/,而是以ws://开头的地址;
  2. 请求头Upgrade: websocketConnection: Upgrade表示这个连接将要被转换为WebSocket连接;
  3. Sec-WebSocket-Key是用于标识这个连接,并非用于加密数据;
  4. Sec-WebSocket-Version指定了WebSocket的协议版本。

随后,服务器如果接受该请求,就会返回如下响应:

  1. HTTP/1.1 101 Switching Protocols
  2. Upgrade: websocket
  3. Connection: Upgrade
  4. 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协议。

聊天系统 websocket 直播聊天的更多相关文章

  1. 关于websocket制作聊天室的的一些总结

    websocket的总结 在一个聊天室系统中,常常使用websocket作为通信的主要方式.参考地址:https://www.jianshu.com/p/00e... 关于自己的看法:websocke ...

  2. 基于WebSocket实现聊天室(Node)

    基于WebSocket实现聊天室(Node) WebSocket是基于TCP的长连接通信协议,服务端可以主动向前端传递数据,相比比AJAX轮询服务器,WebSocket采用监听的方式,减轻了服务器压力 ...

  3. websocket+golang聊天室

    原文地址: http://www.niu12.com/article/3 websocket+golang聊天室 main.go和index.html放在同一目录下 main.go package m ...

  4. Spring之WebSocket网页聊天以及服务器推送

    Spring之WebSocket网页聊天以及服务器推送 转自:http://www.xdemo.org/spring-websocket-comet/ /Springframework /Spring ...

  5. Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G

    code&monkey   Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...

  6. WebSocket 网页聊天室

    先给大家开一个原始的websocket的连接使用范例 <?php /* * recv是从套接口接收数据,也就是拿过来,但是不知道是什么 * read是读取拿过来的数据,就是要知道recv过来的是 ...

  7. 基于websocket vue 聊天demo 解决方案

    基于websocket vue 聊天demo 解决方案 demo 背景 电商后台管理的客服 相关技术 vuex axios vue websocket 聊天几种模型 一对一模型 一对一 消息只一个客户 ...

  8. Websocket直播间聊天室教程 - GoEasy快速实现聊天室

    最近两年直播那个火啊,真的是无法形容!经常有朋友问起,我想实现一个直播间聊天或者我想开发一个聊天室, 要如何开始呢? 今天小编就手把手的教你用GoEasy做一个聊天室,当然也可以用于直播间内的互动.全 ...

  9. 利用Swoole实现PHP+websocket直播,即使通讯代码,及linux下swoole安装基本配置

    swoole安装基本配置 php安装swoole 1. 下载swoole安装 wget http://pecl.php.net/get/swoole-1.9.1.tgz tar -zxvf swool ...

随机推荐

  1. Android在非UI线程中更新UI的方法

    1.使用Thread+Handler实现非UI线程更新UI界面 在UI Thread中创建Handler.用sendMessage(message)或者obtainMessage(result, ob ...

  2. SET IDENTITY_INSERT <Table Name> ON/OFF 转载

    This command is from SQL Server.  This command is to enable the users to set their own value for IDE ...

  3. 手动安装minGW

    minGW是C语言编译包,将GCC编译器在Windows平台上编译软件提供支持. 手工安装minGW是一件很繁琐的事情,但是搞懂它很有用,因为C语言本身是一个很小的语法系统,全靠 各种库在支持,安装m ...

  4. atitit.提升性能AppCache

    atitit.提升性能AppCache 1.1. 起源1 2. 离线存储2 3. AppCache2 3.1. Appcache事件点如图2 3.2. Manifest文件4 3.3. 自动化工具4 ...

  5. django rest framework(10)

    1.权限 2.认证 3.访问频率限制 4.序列化 5.路由 6.视图 7.分页 8.解析器 9.渲染器 10.版本 面试题:你写的类都继承过哪些类? class Vive(object): class ...

  6. 怎么解决ORACLE 中 CHAR类型的索引问题

    在很多场景中,都有如下情况 trim(a.colunm1) = trim(b.colunm2) 应该怎么优化呢? 用到 TRIM 的很多原因是某些系统为了提高查询效率,不使用  ORACLE 的特有的 ...

  7. 设置VMware随系统开机自动启动并引导虚拟机操作系统

    设置VMware随系统开机自动启动并引导虚拟机操作系统 转载 2012年03月15日 19:50:53 标签: vmware / 虚拟机 / windows / parameters / tools  ...

  8. MapReduce实战(六)共同粉丝

    需求: 利用mapReduce实现类似微博中查找共同粉丝的功能.如下: A:B,C,D,F,E,OB:A,C,E,KC:F,A,D,ID:A,E,F,LE:B,C,D,M,LF:A,B,C,D,E,O ...

  9. java文件对话框操作

        完毕文件打开与保存   FileDialog : FileDialog fd = new FileDialog(this); fd.setVisible(true);//或fd.show(); ...

  10. flask 邮箱配置

    http://blog.csdn.net/stan_pcf/article/details/51098126 先进入邮箱设置 POP3/SMTP/IMAP 下面代码来自知乎 https://www.z ...