如何完全实现服务器发送的事件以进行消息轮询

我正在尝试使用API​​与服务器通信。

为了更容易,我写了一个脚本,将使用PHP脚本传递API。

我的目标是每秒查询一次API以查看其队列中是否有新消息。

我被建议使用服务器发送的事件方法,并让服务器仅在有新内容时才向客户端发送响应。

这是我的PHP脚本

 '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; } } ?> 

当用户访问我的页面时,这是我运行的代码

  $(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; } }); }); } });  

我上面的代码不起作用。

我的控制台里没有任何东西。 但是这个错误Firefox can't establish a connection to the server at /icws/poll.php

我怎样才能让它发挥作用? 我通过PHP脚本实现的方式是否正确?

您的事件源php文件的浏览器请求的状态代码是什么? 尝试使用firebug来确保它不是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."} 

为了解决这个问题,我添加了一个类似的监听器事件

  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以及最后一行。 同样重要的是在我的javascript代码中查找位于我的PHP代码和监听器事件中的关键字ping 。 如果你改变它,你必须在2个地方改变它。

我希望这可以帮助别人 :)