2013-02-18 1 views
2

Я создаю систему уведомлений для своего сайта. Я хочу, чтобы зарегистрированные пользователи сразу заметили, когда уведомление было сделано. Как говорят многие, есть только несколько способов сделать это.Как работает Long Polling или Comet с PHP?

Один из них пишет код javascript, чтобы спросить у сервера «Есть ли новые уведомления?» на данном временном интервале. Это называется «Опрос» (я должен быть прав).

Другим является «длинный опрос» или «комета». Как говорит Википедия, длительный опрос похож на опрос. Не спрашивая каждый раз о новых уведомлениях, когда новые уведомления доступны, сервер отправляет их непосредственно клиенту.

Так как я могу использовать Long Polling с PHP? (Не нужен полный исходный код, но способ сделать это) Какова его архитектура/дизайн?

+0

'while (! $ Response) {$ response = do_something(); сон (1); } echo $ response; ' –

+1

Интересный вопрос, только тот, который я искал. Я буду вкладывать щедрость за ответ +50 – samayo

+0

Длительный опрос может быть проблемой для определенных веб-серверов, я думаю (это был период, когда я читал что-нибудь об этом, хотя). Слишком много открытых подключений и т. Д. – NickSlash

ответ

3

Основная идея длительного опроса заключается в том, что вы отправляете запрос, который затем НЕ откликается или прекращается сервером до некоторого желаемого состояния. То есть серверная сторона не «завершает» выполнение запроса, отправив ответ. Вы можете добиться этого, сохранив выполнение в цикле на стороне сервера.

Представьте, что в каждом цикле вы делаете запрос на базу данных или все, что необходимо для вас, чтобы узнать, действительно ли условие, которое вам нужно, истинно. Только когда это вы нарушаете цикл и отправляете ответ клиенту. Когда клиент получает ответ, он немедленно повторно отправляет запрос «длинного опроса», чтобы он не пропустил следующее «уведомление».

Упрощенный пример серверного кода PHP для этого может быть:

// Set the loop to run 28 times, sleeping 2 seconds between each loop. 
for($i = 1; $i < 29; $i++) { 

    // find out if the condition is satisfied. 
    // If YES, break the loop and send response  

    sleep(2); 
} 
// If nothing happened (the condition didn't satisfy) during the 28 loops, 
// respond with a special response indicating no results. This helps avoiding 
// problems of 'max_execution_time' reached. Still, the client should re-send the 
// long-polling request even in this case. 
+0

Можете ли вы привести простой пример, который работает? Я буду предлагать +50 – samayo

+0

Петля для проверки новых уведомлений на стороне сервера? Это замедлит работу сервера. Будет ли он ? –

+0

@ PHP NooB простой пример включено. – marekful

1

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

По существу, вам необходимо избегать того, чтобы apache или веб-сервер обрабатывали запрос. Как и с сервером node.js, вы можете запустить PHP из командной строки и использовать функции server socket для создания сервера и использовать socket_select для обработки сообщений.

Он может технически работать через веб-сервер, поддерживая цикл активным. Тем не менее, накладные расходы на память для поддержания php-процесса активны для HTTP-соединения, как правило, слишком высоки. Создание собственного сервера позволяет вам разделить память между соединениями.

+0

В классическом методе опроса нет (или меньше) проблем, чем комета? –

+1

Классический метод опроса имеет значительные накладные расходы, а также значительно увеличивает количество попаданий на ваш сервер. Однако память не сохраняется между опросами. –

1

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

1) Не долгий опрос более 20 секунд. Некоторые браузеры будут таймаутом. Обычно я устанавливаю свой длительный опрос на 20 секунд и посылаю обратно пустой ответ в этот момент. Затем вы можете использовать javascript для возобновления длительного опроса.

2) Время от времени браузер будет зависать. Чтобы добавить второй уровень проверки ошибок, у меня есть таймер javascript в течение 30 секунд, и если в течение 30 секунд не будет ответа, я откажусь от вызова ajax и запустим его снова.

3) Если вы используете PHP убедитесь, что вы используете session_write_close()

4) Если вы используете Ajax с Jquery вам, возможно, придется использовать abort()

0

Вы можете найти ответ на свой вопрос here. Подробнее here.И вы должны помнить, что при работе с jQuery следует использовать $.ajaxSetup({ cache:false });.

+0

Вы должны объяснить это здесь, а не просто упоминать ссылки. –