Как сбросить текущий вывод в RApache?

Я тестирую использование RApache в качестве SSE (Server Sent Events) и аналогичного (длинный опрос, комета и т. Д.) Серверной части. Кажется, я застрял на том, как очистить мой вывод. Является ли это возможным?

Вот мой тестовый скрипт R:

setContentType("text/plain")

repeat{
    cat(format(Sys.time()),"\n")
    #sendBin(paste(format(Sys.time()),"\n"))
    flush(stdout())
    Sys.sleep(1)
    }

Моя запись в Rapache.conf:

<Location /rtest/sse>
    Options -MultiViews
    SetHandler r-handler
    RFileHandler /var/www/local/rtest/sse.r
</Location>

И я проверяю это, используя wget или curl:

wget -O - http://localhost/rtest/sse
curl http://localhost/rtest/sse

Оба просто сидят там, что означает, что ничего не отправляется.

С помощью sendBin() не сделал никаких изменений, и ни один не использовал flush(),

Если я изменю repeat в for(i in 1:5) затем он сидит там в течение 5 секунд, а затем показывает 5 временных меток (с интервалом в одну секунду). Итак, я считаю, что все остальное работает нормально, и это чисто буферная проблема.

ОБНОВЛЕНИЕ: Глядя на это свежим взглядом через 5 месяцев, я думаю, что мог бы описать проблему более четко: проблема в том, что RApache, похоже, буферизует весь вывод и ничего не отправляет, пока скрипт R не завершится. Чтобы быть полезным для потоковой передачи, он должен каждый раз отправлять данные из Apache и на клиент flush() называется, т. е. пока R-скрипт еще работает. Итак, мой вопрос: есть ли способ заставить RApache так себя вести?

ОБНОВЛЕНИЕ 2 Я попытался добавить flush.console() до или после flush(stdout()) но без разницы Я тоже пробовал setStatus(status=200L) на вершине. И я попробовал SERVER$no_cache=T;SERVER$no_local_copy=T; в верхней части сценария. Снова это не имело никакого значения. (Да, ни один из них не должен был помочь, но это никогда не повредит!)

Вот ссылка на то, как PHP реализует сброс при работе в качестве модуля Apache: http://git.php.net/?p=php-src.git;a=blob;f=sapi/apache2handler/sapi_apache2.c Я думаю, что ключевым моментом является то, что есть вызов ap_rflush(r), Я предполагаю, что RApache не делает ap_rflush() вызов.

1 ответ

Вы передаете неправильный тип MIME. Попробуйте изменить с

setContentType("text/event-stream")

EDIT1:

это попытка (все еще безуспешная), о которой я упоминал в комментарии ниже, реализовать SSE в Rook,

<%
  res$header('Content-Type', 'text/event-stream')
  res$header('Cache-Control', 'no-cache')
  res$header('Connection', 'keep-alive')
  A <- 1

  sendMessage <- function(){
    while(A<=4){
      cat("id: ", Sys.time(), "\n", "data: hello\n\n", sep="")
      A <- A+1
      flush(stdout())
      Sys.sleep(1)
    }
  }

-%>

<% sendMessage() %>

while условие цикла должно было быть всегда TRUE но у меня та же проблема, поэтому мне пришлось сделать конечный цикл...

Хорошая новость в том, что у меня есть данные, поступающие в браузер. Я могу сказать, посмотрев, в инструментах разработчика, на Content-Length в Response Header раздел. в приведенном выше коде указано 114, и вы меняете "Hello" на "Hello!". это скажет 118.

Код js: (вам также понадобится JQuery)

$(document).ready(function(){

  $("button").click(function(){

    var source = new EventSource("../R/sse.Rhtml");

    source.onopen = function(event){
      console.log("readyState: " + source.readyState);
    }

    source.onmessage = function(event){
      $("#div").append(event.data);
    };

    source.onerror = function(event){
      console.log(event);
    };

  });


});

Итак, по существу

1) Соединение открыто (readyState 1)

2) Буферизация все еще там

3) Данные (после буферизации) достигают браузера, но при их правильном получении происходит ошибка.

EIDT2:

Интересно отметить, что brew() в вышеупомянутом файле.Rhtml вывод не буферизуется. На веб-сервере должна быть конфигурация (внутренняя R и Apache), которая буферизует потоки данных.

Как примечание стороны, flush даже не нужно, catпо умолчанию выводится stout(), Итак, варианты:

  1. Конфигурация веб-сервера
  2. R-эквивалент PHP ob_flush(); который всегда используется в любой реализации PHP, которую я видел. это пример
Другие вопросы по тегам