2015-05-16 36 views
4

我正在嘗試使用API​​與服務器進行通信。如何完全實現消息輪詢的服務器發送事件

爲了使它更容易我寫了一個腳本,將使用PHP腳本來傳達API。

我的目標是每秒鐘查詢API以查看隊列中是否有新消息。

我被建議使用server-sent events方法,並讓服務器只在客戶端有新內容時才發送響應。

這裏是我的PHP腳本

<?php 

    // Register autoloader function 
    spl_autoload_register('apiAutoloader'); 
    header("Content-Type: text/event-stream\n\n"); 

    $config = array('host' => 'server:IP',    //REQUIRED - Server Name 
        'port' => 8018,      //REQUIRED - Server Port 
        'userID' => 'user',     //REQUIRED - UserID to login with 
        'password' => '123456',    //REQUIRED - password for the UserID to login with 
        ); 

    try { 

     //create a new instance of icws 
     $icws = new API\ICWS($config); 

     //create a new session 
     $icws->createSession(true);  

     while(1){ 

      $result = $icws->processMessage(); 
      echo json_encode($result); 

      ob_flush(); 
      flush(); 
      sleep(1); 

     } 

    } catch(Exception $e){ 
     echo $e->getMessage(); 
    } 

    function apiAutoloader($className) 
    { 
     $className = ltrim($className, '\\'); 
     $fileName = ''; 
     $namespace = ''; 

     if ($lastNsPos = strripos($className, '\\')) 
     { 
      $namespace = substr($className, 0, $lastNsPos); 
      $className = substr($className, $lastNsPos + 1); 
      $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; 
     } 

     $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; 

     $toLoad = dirname(__FILE__).'/'.$fileName; 

     if (is_file($toLoad) === true) 
     { 
      include $toLoad; 
     } 
    } 
?> 

當用戶訪問我的頁面,這是代碼的我跑

<script> 

    $(function(){ 

     function isset(a, b){ 

      if(typeof a !== "undefined" && a){ 
       return a 
      } 

      return b; 
     } 


     var evtSource = new EventSource("poll.php"); 

     evtSource.onmessage = function(e) { 

      $.each(e.data.calls, function(i, item){ 

       $.each(item, function(z, c){ 

        var interactionId = isset(c.interactionId, 0); 
        var Eic_CallDirection = isset(c.Eic_CallDirection, ''); 
        var Eic_State = isset(c.Eic_State, ''); 
        var AccoRDI_mid = isset(c.AccoRDI_mid, ''); 
        var Eic_RemoteAddress = isset(c.Eic_RemoteAddress, ''); 

        if(Eic_State == '' || Eic_CallDirection == ''){ 
         return; 
        } 

        //incoming call that is not answered 
        if(Eic_CallDirection == 'I' && Eic_State == 'A'){ 
         console.log('Incomming Call From ' + Eic_RemoteAddress + ' MID: ' + AccoRDI_mid); 
         return; 
        } 

        //on hold 
        if(Eic_State == 'H'){ 
         console.log('Phone number ' + Eic_RemoteAddress + ' is on hold'); 
         return; 
        } 

        //voicemail 
        if(Eic_State == 'M'){ 
         console.log('Phone number ' + Eic_RemoteAddress + ' is on leaving a voicemail'); 
         return; 
        } 

        //connected call 
        if(Eic_State == 'C'){ 
         console.log('Live Call With ' + Eic_RemoteAddress); 
         return; 
        } 

        //Dialling call 
        if(Eic_State == 'O'){ 
         console.log('Dialling ' + Eic_RemoteAddress); 
         return; 
        } 

        //Dialling call 
        if(Eic_State == 'R'){ 
         console.log('Outbound call is rining and waiting for answer '); 
         return; 
        } 

        //Call Disconnected 
        if(Eic_State == 'I' || Eic_State == 'E'){ 
         console.log('Hungup with ' + Eic_RemoteAddress); 
         return; 
        } 

       }); 
      }); 
     } 
    }); 
</script> 

上面我的代碼不能正常工作。

我沒有得到任何東西在我的控制檯。但是這個錯誤Firefox can't establish a connection to the server at /icws/poll.php

我怎樣才能使它工作? 我通過PHP腳本實現的方式是否正確?

+0

嘗試使用'ob_end_flush()'代替。看起來緩衝存在問題。 Apache/Nginx? – Axalix

+0

仍然收到錯誤'Firefox無法在/ icws/poll.php.處建立與服務器的連接' – Jaylen

+0

icws-> processMessage();回報? – Zalaboza

回答

1

什麼是瀏覽器請求你的事件源php文件的狀態碼?嘗試使用螢火蟲,以確保它不是404。

也關於PHP代碼。

根據Mozilla源,你包括在你的問題。從服務器 適當的反應,應命名並以新行

header("Content-Type: text/event-stream\n\n");  
while (1) {  
    echo "event: ping\n"; //event name 
    echo 'data: '.json(); //event data 
    Echo "\n\n"; //required 

    ob_flush(); flush(); sleep(1);  
} 

事件例如分離

event: userconnect 
data: {"username": "bobby", "time": "02:33:48"} 

event: usermessage 
data: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."} 
+0

現在仍在工作。這裏是錯誤現在'連接到https://accordi.rdimarketing.com/icws/poll.php在頁面加載時被中斷。' – Jaylen

+0

嘗試直接打開頁面並等待幾分鐘 – Zalaboza

+0

我接受了您的答案我糾正了這個問題之後。我會發佈一個答案,我已經做了一切幫助下一個人:) – Jaylen

1

爲了解決這個問題,我添加了一個偵聽器事件,像這樣

 var evtSource = new EventSource("poll.php"); 

     evtSource.addEventListener("ping", function(e) { 

      var obj = JSON.parse(e.data); 
      processMessages(obj); 

     }, false); 

,我寫我的processMessages功能像這樣

 function processMessages(obj) { 

      $.each(obj.calls, function(i, item){ 

       $.each(item, function(z, c){ 

        var interactionId = isset(c.interactionId, 0); 
        var Eic_CallDirection = isset(c.Eic_CallDirection, ''); 
        var Eic_State = isset(c.Eic_State, ''); 
        var mid = isset(c.mid, ''); 
        var account_id = isset(c.account_id, ''); 
        var Eic_RemoteAddress = isset(c.Eic_RemoteAddress, ''); 

        if(Eic_State == '' || Eic_CallDirection == ''){ 
         return; 
        } 

        //incoming call that is not answered 
        if(Eic_CallDirection == 'I' && Eic_State == 'A'){ 
        var msg = ''; 
         if(mid != ''){ 
          msg = ' MID: ' + mid; 
         } 

         if(account_id != ''){ 
          msg = ' Account ID: ' + account_id; 
         } 
         console.log('Incomming Call From ' + Eic_RemoteAddress + msg); 
         return; 
        } 

        //on hold 
        if(Eic_State == 'H'){ 
         console.log('Phone number ' + Eic_RemoteAddress + ' is on hold'); 
         return; 
        } 

        //voicemail 
        if(Eic_State == 'M'){ 
         console.log('Phone number ' + Eic_RemoteAddress + ' is on leaving a voicemail'); 
         return; 
        } 

        //connected call 
        if(Eic_State == 'C'){ 
         console.log('Live Call With ' + Eic_RemoteAddress); 
         return; 
        } 

        //Dialling call 
        if(Eic_State == 'O' && Eic_CallDirection = 'O'){ 
         console.log('Dialling ' + Eic_RemoteAddress); 
         return; 
        } 

        //Dialling call 
        if(Eic_State == 'R'){ 
         console.log('Outbound call is rining and waiting for answer '); 
         return; 
        } 

        //Call Disconnected 
        if(Eic_State == 'I' || Eic_State == 'E'){ 
         console.log('Hungup with ' + Eic_RemoteAddress); 
         return; 
        } 

       }); 
      }); 
     } 

和我的PHP代碼如下所示

while(1){ 

     $result = array('test' => 'This is a test records'); 
     echo 'event: ping' . "\n"; 
     echo 'data: ' . json_encode($result) . "\n";  
     echo "\n"; //required 

     ob_flush(); flush(); sleep(1); 

    } 

很少有東西在PHP指出。重要的是在每行之後有\n,最後一行有一個。尋找關鍵字ping這是位於我的PHP代碼和我的JavaScript代碼中的偵聽器事件是非常重要的。如果你改變它,你必須在2個地方改變它。

我希望這可以幫助別人:)