Intereting Posts

Как полностью реализовать сервер-отправленные события для опроса сообщений

Я пытаюсь общаться с сервером с помощью API.

для упрощения написания сценария, который будет связывать API с помощью php-скрипта.

Моя цель – сделать запрос API каждый раз, чтобы узнать, есть ли новое сообщение в их очереди.

Мне было рекомендовано использовать метод отправленных сервером событий, и сервер отправляет ответ клиенту только тогда, когда он имеет что-то новое.

Вот мой 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-скриптом?

Каков код состояния в запросе браузера для вашего 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); } в  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 места.

Я надеюсь, что это помогает кому-то 🙂