2013-11-04 47 views
2

他在那裏!Yiiframework消息彈出

如果有一個問題與我正在處理的應用程序中的兩個不同問題有關。

問題1: - 有一個消息系統。用戶可以發送其他消息。我想在用戶收到新消息並且不在收件箱頁面上時實時彈出。

問題2: - 我想創建一個基本的成就係統,其中一個成就可以是(例如):「接收消息」。

現在我認爲這兩種功能都可以通過相同的方式實現。你們中的任何人都有這種實時通信的經驗嗎?我真的不知道從哪裏開始。我真的很喜歡它,如果它不重。

非常感謝。

+3

調查web​​sockets/AJAX輪詢/長輪詢。 – Matt

回答

1

以下是你可能會使用長輪詢(使用jQuery和Yii的)一個樣板:

服務器端:

class MessagesController extends CController { 

    public function actionPoll($sincePk, $userPk) { 
     while (true) { 
      $messages = Message::model()->findAll([ 
       'condition' => '`t`.`userId` = :userPk AND `t`.`id` > :sincePk', 
       'order'  => '`t`.`id` ASC', 
       'params' => [ ':userPk' => (int)$userPk, ':sincePk' => (int)$sincePk ], 
      ]); 

      if ($messages) { 
       header('Content-Type: application/json; charset=utf-8'); 

       echo json_encode(array_map(function($message){ 
        return array(
         'pk' => $message->primaryKey, 
         'from' => $message->from, 
         'text' => $message->text, 
         /* and whatever more information you want to send */ 
        ); 
       }, $messages)); 
      } 

      sleep(1); 
     } 
    } 

} 

客戶端:

<?php 
$userPk = 1; 
$lastMessage = Messages::model()->findByAttributes([ 'userId' => $userId ], [ 'order' => 'id ASC' ]); 
$lastPk = $lastMessage ? $lastMessage->primaryKey : 0; 
?> 

var poll = function(sincePk) { 
    $.get('/messages/poll?sincePk='+sincePk+'&userPk=<?=$userPk?>').then(function(data) { 
     // the request ended, parse messages and poll again 
     for (var i = 0;i < data.length;i++) 
      alert(data[i].from+': '+data[i].text); 

     poll(data ? data[i].pk : sincePk); 
    }, function(){ 
     // a HTTP error occurred (probable a timeout), just repoll 
     poll(sincePk); 
    }); 
} 

poll(<?=$lastPk?>); 

記得要實現一些這種認證可以避免用戶閱讀其他消息。