AJAX 聊天室實現原理終極解析

2021-06-09 06:37:32 字數 4052 閱讀 8894

ajax 聊天室實現原理終極解析

閒來無事,做了乙個ajax聊天室,以前一直想做乙個,因為我和幾個朋友是linux機子,儘管我們的機子上都有apache伺服器,但要傳送乙個資訊卻不是很容易,老是要借助客戶端,有時候吧linux下的qq和gtalk之類的聊天軟體太麻煩,所以呢,就寫了乙個聊天室。

先說一下我實現的這個聊天室的聊天模式:

1,無須註冊,登入之類,開啟頁面就可以聊天。

2,為避免過量冗餘資訊,客戶端只獲取在一定時間以後傳送的資訊,比如10秒內。

3,可以單對單聊天,僅限於乙個對乙個,如果想一對多同時聊天,那麼就必須要註冊登入才能解決。

這樣就簡化了一些聊天的模式了,如果想要實現例如qq,msn,gtalk之類的聊天模式,就必須要用到使用者註冊登入,這樣一來,先有的很多ajax聊天程式都已經設計的很完美了,例如:

while($row=mysql_fetch_array(mysql_query($sql)) )

下面獲取單聊的資訊。因為單聊的視窗通常會和群聊分開的。

$sql="select * from message where dateline > $dateline-$interval and id > $message_id and from_sid != '$sid' and status=0 and to_sid='$sid' order by dateline asc";

好下面在獲取完單聊訊息後,仍然需要執行:

$message_id = $row['id'] > $message_id  ? $row['id'] : $message_id  ; 

以獲取最大的訊息id。

當然了,如果您覺得麻煩,完全可以這樣:

$maxid_sql="select max(id) from message";

因為我們每次取完訊息後,必然會把當前所有的可用資訊取完,只是這樣做增加了一次資料庫查詢。

下面,更新使用者表的 message_id;

$sql="update online set message_id='$message_id'  where sid='$sid' and ip='$ip' limit 1";

好了,這樣下次再取資訊的時候,就會由這個message_id向後開始取,只取 id 比message_id大的資訊。

吐出的最終資料最好是json格式的,這樣也好減少流量,方便處理文字。

您總不希望別人傳送給您資訊的時候,發給你這樣乙個:

2。傳送資訊。

$msg_status =   1;  // 資訊狀態,1表示群,0表示私聊

$toip        =   $user['link_ip'];      // 傳送的目標物件資訊直接由使用者的表裡取,如果沒有單聊,省去。

$touid         =   $user['link_uid'];

$tosid          =   $user['link_sid'];

$nick           =   htmlspecialchars($_post['nick']);    // 這個是使用者傳送訊息時的暱稱。

$message        =   htmlspecialchars($_post['message']); // 訊息體。

$sql="insert into message(status,from_uid,from_sid,from_ip,to_uid,to_sid,to_ip,nick,dateline,message) values('$msg_status','$uid','$sid','$ip','$touid','$tosid','$toip','$nick','$dateline','$message')";

插入訊息體,如果有單聊的話,需要加上判斷:

$sql="select * from online where sid='$link_sid' and ip='$link_ip' limit 1";

而如果不存在    $user2,單聊的物件,那麼,返回失敗訊息,提示使用者傳送訊息已失敗,物件已斷開。

好,吐出訊息:

這裡可用簡化一下處理結果,如果傳送訊息成功了,那麼什麼也不返回,如果失敗了返回0.

這樣做為了省流量。因為畢竟傳送訊息成功的時候比較多,失敗比較少。在客戶端用js取出返回的資料

判斷是否為空,為空,則,傳送成功,不為空,則傳送失敗。

echo $result;

3。單聊請求,如果不提供單聊,3,4兩條可用略過了。

這裡採用的是,向伺服器傳送連線請求,然後由對方選擇是否接納。

當然如果不想讓使用者自己選擇連線某個物件,而是由伺服器自動配對,這就是當今很流行的路過聊天方式。

其實原理非常簡單,例如 luguode.com ,等等,這類聊天非常的多。

簡要說明一下由伺服器自動配對的做法:

第一步:獲取哪些使用者仍是單身:

先說明一下狀態**表示:

online表中的status 字段:為0表示使用者單身,為3表示使用者已經配對。1,2留著有其他用處。

$sql="select * from online where sid !='$sid' and status=0 ";

假如我們取出乙個陣列:$single_onlines;

下面我們取出乙個隨機的使用者:

srand((double)microtime()*1000000);

// 初始化隨機數種子,php 4以後版本據說已不在需要,

// 但很多時候,我還是需要這句才能得到正確的隨機數,****!

$target_index    =    rand( 0 , count($single_onlines)-1) ; //隨機下標

$target_sid    =     $single_onlines[$target_index]['sid'] ;

$target_ip        =      $single_onlines[$target_index]['ip'] ;

// 獲取到目標的sid 了,下面同時更新使用者和我!

$sql="update online set status='3', link_sid='$target_sid', link_ip='$target_ip' where sid='$sid' and ip='$ip' limit 1 ";// 更新我的狀態

$sql="update online set status='3', link_sid='$sid', link_ip='$ip' where sid='$target_sid' and ip='$target_ip' limit 1 "; // 更新目標狀態

當然了,在更新前,需要做一些簡要的判斷,例如,我自己是不是已經是3了阿,是表示我已經是和別人建立單聊了,那麼就返回乙個錯誤了。

說到這類不知道您發現問題了沒?就是,當我沒有請求和別人單聊的時候,也可能會被別人啪的連上了。

簡單解釋一下:例如現在有三個人 a,b,c,我是a,這三個人都是單身,當我向伺服器發出請求連線的時候,

這個時候,伺服器隨機找出了b,而b這個時候並沒有向伺服器發出連線請求,也會被啪連上了。

所以我們就可以加乙個狀態判斷。例如:status=1表示使用者正在向伺服器發出連線請求。

0,表示使用者什麼也沒有做,也不想和別人單聊。

而這個時候,就從那些狀態為1的使用者裡面找出一些,隨機連線。

如果沒有單身了,那麼先把使用者狀態更新為1,返回沒有找到的提示。

最後需要增加乙個重新整理使用者狀態,

if($user['status']==3)

} 然後還需要提供乙個手動斷開連線的處理,這就比較簡單啦,直接把自己的狀態,和對方狀態更新為0,同時清楚掉link_uid....之類的

下面說說前台,基於jquery的!

前台比較簡單。

chat={};

chat.get=function(),function(data));

//scroll('im'); 這裡加乙個滾動效果,可用把視窗自動滾動到最底部。

}settimeout('chat.get()',3000);

},'json');

}function scroll(id)

其他的請求就略過了,因為比較簡單。原理都差不多了。

好了,到這裡就基本講解完了乙個ajax聊天室的原理,如果是註冊聊天,實行起來會比這個容易些!

AJAX 聊天室實現原理終極解析

閒來無事,做了乙個ajax聊天室,以前一直想做乙個,因為我和幾個朋友是linux機子,儘管我們的機子上都有apache伺服器,但要傳送乙個資訊卻不是很容易,老是要借助客戶端,有時候吧linux下的qq和gtalk之類的聊天軟體太麻煩,所以呢,就寫了乙個聊天室。先說一下我實現的這個聊天室的聊天模式 1...

php html實現聊天室

1.最簡單的方式 不斷重新整理頁面 資料庫建立 create table chat chattime datetime,nick char 10 words char 150 login.php 請輸入您的暱稱 cdisplay.php conn mysql connect 127.0.0.1 ro...

ajax無重新整理聊天室系統

php愛好者聊天室公告 歡迎來到聊天室 資料庫sql語句 create table message id int unsigned not null auto increment,msg varchar 32 not null,sender varchar 6 not null,receiver v...