Как сделать в реальном времени «Пользователь печатает» уведомление всем в чате

Я хочу написать чат-приложение, используя jQuery и PHP. Часть, в которой мне нужна помощь, – это когда пользователь в режиме реального времени «Evx» печатает сообщение, а затем показывает это сообщение всем другим пользователям в режиме реального времени. Это будет похоже на то, как у Skype есть ручка ../ и как Facebook имеет уведомление, когда пользователь набирает.

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

Вот что я пробовал до сих пор:

//time delay before ajax call var delay = (function() { var timer = 0; return function(callback, ms) { clearTimeout(timer); timer = setTimeout(callback, ms); }; })(); $('#usermsg').keydown(function() { if ($('#usermsg').val().length === 5) { delay(function() { $.ajax({ url: "addusertyping.php", cache: false, success: function() { } }); }, 5000); } }); $('#usermsg').keyup(function() { if ($('#usermsg').val().length >= 6) { // here I should basically check for // an update from server or what not. } });​ 

Может кто-нибудь объяснить шаги и информацию о том, как добиться ввода пользователя в реальном времени, используя то, что я пробовал выше, в качестве отправной точки?

Подход, который используют сайты Facebook и Google Talk при использовании чата, заключается в использовании решений, которые используют модель запроса / ответа в Интернете с использованием Comet или Reverse AJAX.

Веб 1.0:

В традиционных реализациях Web 1.0, таких как ваш, браузер инициирует запрос на сервер. Сервер отвечает данными, которые клиентский код отображает в представлении.

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

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

Comet / Reverse AJAX:

Поскольку сервер не может инициировать ответы в браузере без запроса, для имитации процесса отправки на сервер уведомлений о событиях используется метод, называемый «обратный AJAX» или «комета».

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

Существуют решения Comet для PHP, поэтому это то, что вы можете выполнить с помощью вашей существующей платформы; однако я не могу рекомендовать. Вам также понадобится библиотека на стороне клиента, чтобы облегчить открытие соединений Comet. Проверьте библиотеку JavaScript ComjoD Dojo .

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

При поиске библиотеки, которая облегчает комету, также неплохо выбрать тот, который облегчает Continuations, что позволяет гарантировать, что потоки, ожидающие отправки ответа, могут быть выпущены для выполнения других задач, а не ожидания idly. С таким решением некоторые серверы Comet легко масштабируются до более чем 20 000 подключений!

Вот статья, в которой описывается, как реализовать комету на PHP . Кроме того, вы можете найти этот вопрос StackOverflow полезным, поскольку он описывает проблемы использования Comet на PHP .

Конструктивные соображения:

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

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

Наконец, ваше сообщение о вводе пользователя должно иметь некоторую задержку на нем, так что когда пользователь печатает, его или ее браузер будет уведомлять об этом только один раз каждые X секунд. Если вы привязываете пользователя к событию нажатия клавиши, которое просто забивает сервер с помощью запросов AJAX, то вы просто унизите свое соединение с Comet обратно в опрос.

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

Легкие решения ?:

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