@devunion

SSO и Yii: почему не работает простой пример?

Добрый день, есть простой скрипт, который работает без Yii:

<?
    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache');

    sendMsg("test message");

    function sendMsg($msg) {
        echo "data: $msg" . PHP_EOL;
        echo PHP_EOL;
        ob_flush();
        flush();
    }
?>

С ним все в порядке. Клиент получает сообщения.

Далее я пробую использовать этот код в контроллере Yii:

function sendMsg($msg)
    {
        echo $msg . PHP_EOL;
        echo PHP_EOL;
        ob_flush();
        flush();
    }

    function actionStream()
    {
        $all = State::model()->findAll();

        if (count($all) == 0) {
            $s = new State();
            $s->update_requested = new CDbExpression('NOW()');
            $s->save();
        } else {
            $s = $all[0];
        }

        header('Content-Type: text/event-stream');
        header('Cache-Control: no-cache');

        $this->sendMsg($s->update_requested);
    }


Теперь сообщение не доходит до клиента:

open: [object Event]
error: undefined
open: [object Event]
error: undefined
open: [object Event]
error: undefined

Код клиента стандартный:
var source = new EventSource(URL_EVENT_STREAM);

    source.addEventListener('message', function (e) {
        console.log('message: ' + e.data);
    }, false);

    source.addEventListener('open', function (e) {
        console.log('open: ' + e);
    }, false);

    source.addEventListener('error', function (e) {
        console.log('error: ' + e.readyState);

        if (e.readyState == EventSource.CLOSED) {
            console.log('error: ' + e);
        }
    }, false);


Подскажите, в чем проблема. Сервер один и тот же. Заголовки ответа одинаковые.
Перепробовал все советы, которые нашел тут по теме. Не помогает...
  • Вопрос задан
  • 3427 просмотров
Решения вопроса 1
@evilJ0e
Много ошибок, парень.

Для начала укажи пустой шаблон. Тогда ты сможешь отправить необходимые заголовки:
public $layout='//layouts/main';

В стандарте прописано, что сообщение надо слать следующим образом:
"data: сообщение\n\n"
или
"data: сообщение из двух строк\n"
"data: сообщение из двух строк\n\n"

Перепиши свою функцию, например, так:
function sendMsg($msg)
{
    echo "data: " . $msg . "\n\n";
    ob_flush();
    flush();
}


Еще, кажется, в контроллере необходим обязательный actionError().

Вот мой рабочий код данного примера. Права доступа остались с прошлого проекта:
class SiteController extends Controller
{
    public $layout='//layouts/main';

    public function filters()
    {
        return array(
            'accessControl',
            'postOnly + delete',
        );
    }

     public function actions()
     {
          return array(
              'page'=>array(
                   'class'=>'CViewAction',
               ),
          );
     }

    public function accessRules() {
        return array(
            array('allow',
                'actions' => array('stream'),
                'users' => array('*'),
            ),
            array('allow',
                'actions' => array('foo'),
                'users' => array('@'),
            ),
            array('allow', 
                'actions'=>array('foo'),
                'users'=>array('admin'),
            ),
            array('deny', 
                'users'=>array('*'),
            ),
        );
    }

    public function actionError()
    {
          if($error=Yii::app()->errorHandler->error)
          {
               if(Yii::app()->request->isAjaxRequest)
	              echo $error['message'];
	    	else
	              $this->render('error', $error);
	    }
     }

    protected function sendMessage($msg)
    {
        echo "data: " . $msg . "\n\n";
        ob_flush();
        flush();
    }

    protected function sendResponse($status = 200, $body = '', $contentType = 'application/json', $cache = 'no-cache')
    {
        $statusHeader = 'HTTP/1.1 ' . $status;
        header( $statusHeader );
        header( 'Content-type: ' . $contentType );
        header( 'Cache-Control: ' . $cache );

        self::sendMessage( $body );
    }

    function actionStream()
    {
        $t = 'message';

        self::sendResponse( 200, $t, 'text/event-stream' );
    }
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
metamorph
@metamorph
Для начала попробуйте сразу после $this->sendMsg поставить exit; или Yii::app()->end();
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы