Как мне реализовать базовый & ldquo; Long Polling & rdquo ;?

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

var myarr = [{somfield1: 'x', somefield2: 'y'},
{somfield1: 'a', somefield2: 'b'},
{somfield1: 'i', somefield2: 'j'}];

Таким образом вы можете использовать регулярный цикл и иметь порядок вставки. Затем вы можете использовать метод сортировки массива, чтобы отсортировать его в новом массиве, если это необходимо.

762
задан Sinister Beard 25 January 2016 в 09:33
поделиться

7 ответов

Это более просто, чем я первоначально думал.. В основном у Вас есть страница, которая ничего не делает, пока данные, которые Вы хотите отправить, не доступны (скажите, новое сообщение прибывает).

Вот действительно основной пример, который отправляет простую строку после 2-10 секунд. 1 в 3 шансах возврата ошибки 404 (для показа обработки ошибок в ближайшем примере JavaScript)

msgsrv.php

<?php
if(rand(1,3) == 1){
    /* Fake an error */
    header("HTTP/1.0 404 Not Found");
    die();
}

/* Send a string after a random number of seconds (2-10) */
sleep(rand(2,10));
echo("Hi! Have a random number: " . rand(1,10));
?>

Примечание: С реальным сайтом, выполняя это на обычном веб-сервере как Apache быстро свяжет все "рабочие потоки" и оставит неспособным ответить на другие запросы.. Существуют пути вокруг этого, но рекомендуется записать "сервер длинного опроса" в чем-то как Python , скрученный , который не полагается на один поток на запрос. cometD является популярным (который доступен на нескольких языках), и , Торнадо является новой платформой, сделанной специально для таких задач (это было создано для долго опрашивающего кода FriendFeed)..., но как простой пример, Apache является более, чем соответствующим! Этот сценарий мог легко быть записан на любом языке (я выбрал Apache/PHP, поскольку они очень распространены, и я, оказалось, выполнял их локально)

Затем в JavaScript, Вы запрашиваете вышеупомянутый файл (msg_srv.php) и ожидаете ответа. Когда Вы добираетесь один, Вы реагируете на данные. Тогда Вы запрашиваете файл и ожидаете снова, реагируете на данные (и повторение)

, Что следует, пример такой страницы.. Когда страница загружается, она отправляет начальный запрос для msgsrv.php файл.. Если это успешно выполняется, мы добавляем сообщение к #messages отделение, то после 1 секунды мы вызываем waitForMsg функцию снова, которая инициировала ожидание.

1 секунда setTimeout() действительно ограничитель базовой скорости, она хорошо работает без этого, но если msgsrv.php всегда возвраты немедленно (с синтаксической ошибкой, например) - Вы лавинно рассылаете браузер, и она может быстро замерзнуть. Это было бы лучше сделано, проверив, содержит ли файл допустимый ответ JSON и/или хранение рабочего общего количества requests-per-minute/second и приостановки соответственно.

, Если ошибки страницы, это добавляет ошибку к #messages отделение, ожидает 15 секунд и затем попробовал еще раз (идентичный тому, как мы ожидаем спустя 1 секунду после каждого сообщения)

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

Так или иначе, эти long_poller.htm код, с помощью платформы jQuery:

<html>
<head>
    <title>BargePoller</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript" charset="utf-8"></script>

    <style type="text/css" media="screen">
      body{ background:#000;color:#fff;font-size:.9em; }
      .msg{ background:#aaa;padding:.2em; border-bottom:1px #000 solid}
      .old{ background-color:#246499;}
      .new{ background-color:#3B9957;}
    .error{ background-color:#992E36;}
    </style>

    <script type="text/javascript" charset="utf-8">
    function addmsg(type, msg){
        /* Simple helper to add a div.
        type is the name of a CSS class (old/new/error).
        msg is the contents of the div */
        $("#messages").append(
            "<div class='msg "+ type +"'>"+ msg +"</div>"
        );
    }

    function waitForMsg(){
        /* This requests the url "msgsrv.php"
        When it complete (or errors)*/
        $.ajax({
            type: "GET",
            url: "msgsrv.php",

            async: true, /* If set to non-async, browser shows page as "Loading.."*/
            cache: false,
            timeout:50000, /* Timeout in ms */

            success: function(data){ /* called when request to barge.php completes */
                addmsg("new", data); /* Add response to a .msg div (with the "new" class)*/
                setTimeout(
                    waitForMsg, /* Request next message */
                    1000 /* ..after 1 seconds */
                );
            },
            error: function(XMLHttpRequest, textStatus, errorThrown){
                addmsg("error", textStatus + " (" + errorThrown + ")");
                setTimeout(
                    waitForMsg, /* Try again after.. */
                    15000); /* milliseconds (15seconds) */
            }
        });
    };

    $(document).ready(function(){
        waitForMsg(); /* Start the inital request */
    });
    </script>
</head>
<body>
    <div id="messages">
        <div class="msg old">
            BargePoll message requester!
        </div>
    </div>
</body>
</html>
503
ответ дан Minko Gechev 25 January 2016 в 09:33
поделиться

Я использовал это для понимания с Кометой, я также настроил Комету с помощью Java сервер Glassfish и нашел много других примеров путем подписки на cometdaily.com

11
ответ дан adam 25 January 2016 в 09:33
поделиться

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

сервер тогда похож на это.

while (!hasNewData())
    usleep(50);

outputNewData();

Так, запрос Ajax переходит к серверу, вероятно, включая метку времени того, когда это было последнее обновление так, чтобы Ваш hasNewData() знал, какие данные Вы уже получили. Сервер тогда находится в цикле, спя, пока новые данные не доступны. Все время Ваш запрос Ajax все еще соединен, просто зависнув там ожидающий данных. Наконец, когда новые данные доступны, сервер дает их Вашему запросу Ajax и закрывает соединение.

24
ответ дан Greg 25 January 2016 в 09:33
поделиться

У меня есть действительно простой пример чата как часть слякоть .

Редактирование : (начиная с общей вставки их кода в здесь)

Это - полный основанный на JSON многопользовательский чат с помощью длинного опроса и слякоть . Это демонстрация из как сделать вызовы, поэтому, проигнорируйте проблемы XSS. Никто не должен развертывать это, не санируя его сначала.

Уведомление, что у клиента всегда есть соединение с сервером, и как только любой отправляет сообщение, все должны видеть его примерно немедленно.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- Copyright (c) 2008 Dustin Sallings <dustin+html@spy.net> -->
<html lang="en">
  <head>
    <title>slosh chat</title>
    <script type="text/javascript"
      src="http://code.jquery.com/jquery-latest.js"></script>
    <link title="Default" rel="stylesheet" media="screen" href="style.css" />
  </head>

  <body>
    <h1>Welcome to Slosh Chat</h1>

    <div id="messages">
      <div>
        <span class="from">First!:</span>
        <span class="msg">Welcome to chat. Please don't hurt each other.</span>
      </div>
    </div>

    <form method="post" action="#">
      <div>Nick: <input id='from' type="text" name="from"/></div>
      <div>Message:</div>
      <div><textarea id='msg' name="msg"></textarea></div>
      <div><input type="submit" value="Say it" id="submit"/></div>
    </form>

    <script type="text/javascript">
      function gotData(json, st) {
        var msgs=$('#messages');
        $.each(json.res, function(idx, p) {
          var from = p.from[0]
          var msg = p.msg[0]
          msgs.append("<div><span class='from'>" + from + ":</span>" +
            " <span class='msg'>" + msg + "</span></div>");
        });
        // The jQuery wrapped msgs above does not work here.
        var msgs=document.getElementById("messages");
        msgs.scrollTop = msgs.scrollHeight;
      }

      function getNewComments() {
        $.getJSON('/topics/chat.json', gotData);
      }

      $(document).ready(function() {
        $(document).ajaxStop(getNewComments);
        $("form").submit(function() {
          $.post('/topics/chat', $('form').serialize());
          return false;
        });
        getNewComments();
      });
    </script>
  </body>
</html>
41
ответ дан j0k 25 January 2016 в 09:33
поделиться

Thanks for the code, dbr. Just a small typo in long_poller.htm around the line

1000 /* ..after 1 seconds */

I think it should be

"1000"); /* ..after 1 seconds */

for it to work.

For those interested, I tried a Django equivalent. Start a new Django project, say lp for long polling:

django-admin.py startproject lp

Call the app msgsrv for message server:

python manage.py startapp msgsrv

Add the following lines to settings.py to have a templates directory:

import os.path
PROJECT_DIR = os.path.dirname(__file__)
TEMPLATE_DIRS = (
    os.path.join(PROJECT_DIR, 'templates'),
)

Define your URL patterns in urls.py as such:

from django.views.generic.simple import direct_to_template
from lp.msgsrv.views import retmsg

urlpatterns = patterns('',
    (r'^msgsrv\.php$', retmsg),
    (r'^long_poller\.htm$', direct_to_template, {'template': 'long_poller.htm'}),
)

And msgsrv/views.py should look like:

from random import randint
from time import sleep
from django.http import HttpResponse, HttpResponseNotFound

def retmsg(request):
    if randint(1,3) == 1:
        return HttpResponseNotFound('<h1>Page not found</h1>')
    else:
        sleep(randint(2,10))
        return HttpResponse('Hi! Have a random number: %s' % str(randint(1,10)))

Lastly, templates/long_poller.htm should be the same as above with typo corrected. Hope this helps.

8
ответ дан 22 November 2019 в 21:24
поделиться

This is a nice 5-minute screencast on how to do long polling using PHP & jQuery: http://screenr.com/SNH

Code is quite similar to dbr's example above.

16
ответ дан 22 November 2019 в 21:24
поделиться

Команда MS Patterns and Practices создала Enterprise Library в качестве ответа на этот вопрос для множества распространенных сценариев. EntLib включает в себя кэширование, а также доступ к данным, проверку, ведение журнала, обработку исключений и т. Д. Мы использовали его годами и не думали бы начинать новый проект без него.

http://www.codeplex.com / entlib

А также домашняя страница P&P, http://msdn.microsoft.com/en-us/practices/default.

9
ответ дан 22 November 2019 в 21:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: