2010-10-06 4 views
2

Я пытаюсь реализовать комету в своем приложении и, будучи неопытным с JavaScript, не знаю, как сделать клиентскую сторону.Реализация кометы на стороне клиента

Когда сервер получает запрос, он просто держит его открытым и записывает в него данные при необходимости:

def render_GET(self, request): 
    print "connected" 
    request.write("Initiated\r\n") 
    reactor.callLater(random.randint(2, 10), self._delay, request) 
    return NOT_DONE_YET; 

def _delay(self, request): 
    print "output" 
    self.count += 1 
    request.write("Hello... {0}\r\n".format(self.count)) 
    reactor.callLater(random.randint(2, 10), self._delay, request) 

Я использую JQuery на стороне клиента до сих пор, но я не могу понять как заставить его работать с сервером. I've been looking at the jQuery.AJAX documentation, и ни один из обратных вызовов не сказал: «Эй, я только что получил данные!», Они только говорят: «Запрос закончен».

Я думал, что функция dataFilter() было то, что я хотел, так как она позволяет обрабатывать необработанные данные перед завершает запрос, но это только позволяет вам сделать это просто перед тем завершает запрос, а не как вы получаете данные.

Итак, как я могу получать данные непрерывно через открытый запрос? Как вы можете видеть в примере на python, каждый фрагмент данных разделен на \r\n, поэтому я хочу, чтобы JavaScript работал как линейный приемник. Возможно ли это с помощью jQuery или мне нужно напрямую играть с XMLHttpRequest/ActiveXObject? Есть ли (простая, легкая) библиотека, доступная для линейного приемника?

Я надеюсь услышать о существующей библиотеке и, как реализовать это самостоятельно, так как до сих пор у меня была плохая неудача с библиотеками комет, и на данный момент я надеюсь просто написать код Мне нужно и не беспокоить всю библиотеку.

ответ

2

Посмотрев на некоторые другие вопросы Comet/jQuery, я наткнулся на это: http://code.google.com/p/jquerycomet/, который выглядит как плагин jQuery, который делает то, что вам нужно. Если вы хотите посмотреть, как это работает, я просто буду копаться в источнике.

Вопрос, где я нашел отличную информацию, - here.

+0

Удивительный, спасибо –

+3

Теперь проект выглядит полностью мертвым. –

2

Стандартная методика заключается в том, чтобы выполнять длинный запрос опроса через AJAX (стандартный вызов с очень длинным таймаутом), а затем, получая ответ, ваш обратный вызов инициирует другой длинный опрос при его вызове. Если истечение времени ожидания истекает, вы повторно отправляете запрос с помощью механизма обработки ошибок. Вместо того, чтобы иметь один длинный запрос, который периодически что-то делает (например, метод «бесконечного iframe»), он использует серию длинных запросов на получение данных, поскольку сервер имеет его доступным.

function longPoll(url, data, cb) 
{ 
     $.ajax({ 
      url: url, 
      data: data, 
      timeout: Number.MAX_VALUE, 
      ...other options... 
      success: function(result) { 
       // maybe update the data? 
       longPoll(url, data, cb); 
       cb.call(this,result); 
      }, 
      error: function() { 
       longPoll(url, data, cb); 
      } 
     } 
} 
+0

Я действительно пробовал этот метод, но я надеялся, что смогу просто записать данные на транспорт, а не повторно инициировать так много запросов. Было бы намного проще просто пропустить объект вокруг, чем он мог бы повторно получить запрос, повторно аутентифицировать его, повторно добавить в список и т. Д. –

+0

@tvanfosson Можете ли вы подробнее рассказать о полезности этого метода ? Я не вижу никаких преимуществ этого решения по сравнению с методом «бесконечного iframe». – Pacerier

0

Этот код является самым простым из всех, что я когда-либо видел.

var previous_response_length = 0 
    , xhr = new XMLHttpRequest(); 

xhr.open("GET", "http://127.0.0.1:7379/SUBSCRIBE/hello", true); 
xhr.onreadystatechange = checkData; 
xhr.send(null); 

function checkData() { 
    if(xhr.readyState == 3) { 
    response = xhr.responseText; 
    chunk = response.slice(previous_response_length); 
    previous_response_length = response.length; 
    console.log(chunk); 
    } 
};