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{width:500px;height:400px;overflow:auto;border:1px solid #ccc;float:left;}
#userlist{width: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="width: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));    
    
}

?>

 

以上就是這次的全部內容!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM