• php实现聊天室功能


    原理:长连接

    一、长连接与短连接

    短连接:客户端与服务端每进行一次报文收发交易时才进行通讯连接、交易完毕后立即断开连接。

    长连接:客户端与服务端先建立连接, 连接建立后不断开,然后在进行报文发送和接收。

    二、操作过程

    短连接的操作步骤是:

    建立连接——数据传输——关闭连接——数据传输——关闭连接

    长连接的操作步骤是:

    建立连接——数据传输……(保持连接)……(数据传输)——关闭连接

    三、优缺点

    短连接:

    常规的短连接模式下,都是通过不间断刷新请求实现的,比如每间隔3秒发送一次Ajax请求,3秒更新一下数据,然后就这样不间断刷新下去,直到用户关闭网页。

    弊端:如果用户很长时间都没有操作,每次刷新都不会返回新数据,这样就造成了资源的浪费,很多请求都是没必要的;用户的输入,跟数据的请求不是同步的,会造成一定的信息延迟。

    长连接:

    Ajax长连接它的刷新是根据数据来执行的,如果有新数据返回,接收并解析显示数据,然后发起新的Ajax请求,如果一段时间内,用户没有操作,则连接出于睡眠状态,一直等待有用户输入或者请求超时,然后发起下个Ajax请求。

    好处:每个信息都会即时推送到客户端,延迟极少;每次请求都是有意义的,比短连接效率高很多。

    弊端:一个用户量很多,并且操作非常频繁的网站,长连接模式也会出现过于频繁的刷新问题。目前IE对于HTTP连接数是有限制的,每个网页只能同时进行两个长连接,第三个长连接也会被阻塞。

    四、实现长连接原理

    长连接需要客户端先向服务器端发送一个请求,服务器端进行不间断的检测,做一个死循环,如果有新数据就推送,如果没有新数据,就一直阻塞。服务器端判断里重要一行代码:usleep(10);就是暂停10毫秒,缓解一下CPU压力。大意就是把前端的循环,搬到了服务器端,减少了网络传输的环节。

    五、服务器端优化

    如果用长连接,必然会给服务器端造成极大的压力,可以考虑放到memcache中;或者为了减小内存的开销,将聊天记录存到文件里。

    六、核心代码

    chat.php

    <html>
    <head>
    <title>聊天室</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script src="../jquery.min.js"></script>
    <script>
    $(function(){
        $("#post").click(function(){
            
        var content=$("#content").val();
        if(!$.trim(content)){
           alert('请填写内容');
           return false;
        }
        $("#content").val("");
    
        $.post("ajax.php", {content:content});});
    })
        
        function getData(msg){
            if(msg == undefined)
            {
                msg = '';    
            }
            $.post("get.php",{"msg":msg},function(data){
                //var myjson = eval("("+data+")");
                if(data){
                    var chatcontent = '';
                    var obj = eval('('+data+')');
                    $.each(obj,function(key,val){
                        chatcontent += "<div class='username'>"+val['username']+" 说:</div>";
                        chatcontent += "<div class='content'>"+val['content']+"</div>";
                    })
                    $("#chatshow").html(chatcontent);
                }
                
                getData();    
            })    
        }
        
        // function getUser(msg){
        //     if(msg == undefined){
        //         msg = '';    
        //     }
        //     $.post("getuser.php",{"msg":msg},function(data){
        //         //var myjson = eval("("+data+")");
        //         if(data){
        //             var chatcontent = '';
        //             var obj = eval('('+data+')');
        //             $.each(obj,function(key,val){
        //                 chatcontent += "<div class='username'>"+val['username']+" 说:</div>";
        //                 chatcontent += "<div class='content'>"+val['content']+"</div>";
        //             })
        //             $("#chatshow").html(chatcontent);
        //         }
        //         getData();    
        //     })    
        // }
        
        getData("one");
        
        
    
        // $(function(){
        //     $("#userlist p").click(function(){
        //         $("#content").val("@"+$(this).text()+" ");    
        //     })    
        // })
        
        // $(function(){
        //     $(document).keypress(function(e){
        //         if(e.ctrlKey && e.which == 13 || e.which == 10) { 
                       
        //             var content=$("#content").val();
        //             if(!$.trim(content)){
        //                alert('请填写内容');
        //                return false;
        //             }
        //             $("#content").val("");    
        //             $.post("ajax.php", {content:content});
        //         }      
        //     })
        //     //alert(event.clientX+document.body.clientWidth);
        // })
        
        /*window.onbeforeunload=function (){ 
            //return("===onbeforeunload==="); 
            if(event.clientX>document.body.clientWidth && event.clientY < 0 || event.altKey){ 
                return("你关闭了浏览器"); 
            }else{ 
                return(document.body.clientWidth); 
            } 
        } */
        
    </script>
    <style>
    #chat{margin:0 auto;}
    #chatshow{500px;height:400px;overflow:auto;border:1px solid #ccc;float:left;}
    #userlist{100px;height:400px;overflow:auto;border:1px solid #ccc;float:left;margin-right:2px;}
    #userlist p{color:#0F0; cursor:pointer;}
    .clearboth{clear:both;}
    .username{font-weight:bold;color:#00F;font-size:12px;margin-bottom:3px;margin-top:8px;}
    </style>
    </head>
    <body>
    <div id="chat">
    <div id="userlist">
    <div style="font-size:12px;font-weight:bold;">在线用户列表</div>
    <div class="userlist">
    <?php 
        // $dsn = "mysql:host=localhost;dbname=test;charset=utf8'";
     //    $db = new PDO($dsn, 'root', 'root');
        $db = new PDO('mysql:dbname=test;host=127.0.0.1;charset=utf8', 'root', 'adminroot');
        $rs = $db->prepare("select * from chat where is_login = '1'");
        $rs->execute();
        while($row = $rs->fetch()){
            echo '<p>'.$row['username'].'</p>';    
        }
    ?>
    </div>
    </div>
    <div id="chatshow"></div>
    </div>
    <div class="clearboth"></div>
    <div>
    <textarea name="content" id="content" style="600px;height:100px"></textarea>
    <input type='button' name='tj' id="post" value='发布' >
    </div>
    </body>
    </html>

    ajax.php

    <?php
    /*session_start();
    $mem = new Memcache;
    $mem->connect("localhost",11211);
    if(isset($_POST['content'])){
        $con['username'] = $_SESSION["username"];
        $con['content'] = $_POST["content"];
        
        $data = $mem->get('chat');
        $data[] = $con;
        $mem->set("chat",$data,0,0);    
    }
    $mem->close();
    */
        if(isset($_POST['content'])){
            session_start();
            $filename = date("Ymd",time()).".txt";
            if(file_exists($filename)){
                $content = file_get_contents($filename);
                $data = json_decode($content,true);        
                $con['username'] = $_SESSION["username"];
                $con['content'] = $_POST["content"];
                $data[] = $con;
                $file = fopen($filename,"w");
                fwrite($file,json_encode($data));
                fclose($file);    
            }else{
                $file = fopen($filename,"w");
                $con['username'] = $_SESSION["username"];
                $con['content'] = $_POST["content"];
                $data[] = $con;
                fwrite($file,json_encode($data));
                fclose($file);    
            }
                
        }
    
    
    
    ?>

    get.php

    <?php 
    /*require 'conn.inc';
    function getData(){
        $sql="SELECT count(*) FROM  `talkroom`";
        $res=mysql_query($sql);
        $count = mysql_fetch_row($res);
        
        return $count;    
    }
    $old = getData();
    
    while(true){
        $new = getData();
        if($new[0]>$old[0]){
            //echo json_encode($new['data']);
            //print_r($new);
            echo '2222222222'.'<br/>';
        }
        //echo '<br />11111111111111111111111111111111111111111111111111111111111111111111';
        usleep(1000);
    }
    */
    /*set_time_limit(0);
    $mem = new Memcache;
    $mem->connect("localhost",11211);
    
    $count = count($mem->get("chat"));
    $com = true;
    //$mem->delete('chat');
    if($_POST['msg'] == "one"){
        exit(json_encode($mem->get("chat")));    
    }
    if($_POST['msg'] == "break"){
        $com = false;    
    }
    $time1 = time();
    while(true){
        if($com){
            $data = $mem->get("chat");
            if(count($data)>$count){
                echo json_encode($data);
                break;
            }
            usleep(300);
        }else{
            break;    
        }
    }
    $mem->close();*/
    
    
    set_time_limit(0);
    $filename = date("Ymd",time()).".txt";
    if(file_exists($filename)){
        $content = file_get_contents($filename);
        $data = json_decode($content,true);        
        $count = count($data);
        // echo $count;die;
        if($_POST['msg'] == "one"){
            exit(json_encode($data));    
        }
        
        while(true){
            
            $contents = file_get_contents($filename);
            $datas = json_decode($contents,true);
            $counts = count($datas);    
            if($counts>$count){
                echo json_encode($datas);
                break;
            }
            usleep(300);
        }
    }else{
        $file = fopen($filename,"w");
        $con['username'] = "系统消息";
        $con['content'] = "欢迎来到EPGO聊天室";
        $data[] = $con;
        fwrite($file,json_encode($data));
        fclose($file);
        
        exit(json_encode($data));    
        
    }
    
    ?>

    以上就是这次的全部内容!

  • 相关阅读:
    小试SQLServer中的CLR特性
    转:memcached命令行参数说明
    2012年9月19日最新整理的日本产品(日货)名单!
    转:Memcached Java Client API详解
    刚写的一个小案例,实现多选的添加及删除
    SVG中的常用标签
    转:网页启用Gzip压缩 提高浏览速度
    SVG案例:著名的PostScript老虎图片
    SVG文档:SVG编程经典教程(转)
    实用技巧:利用SQL Server的扩展属性自动生成数据字典
  • 原文地址:https://www.cnblogs.com/jingxiaoniu/p/7056209.html
Copyright © 2020-2023  润新知