'

AJAX-чат на prototype.js

Понравилась презентация – покажи это...





Слайд 0

AJAX-чат на prototype.js RAD с помощью библиотеки prototype.js на примере AJAX-чата мастер-класс Александр Шуркаев GooDoo IT / Newmedia Stars www.prototypejs.ru, htmlcoder.visions.ru alshur@ya.ru


Слайд 1

2 Почему чат на AJAX’е? Передача малого количества данных Быстрое обновление данных Нет необходимости в наличии Java-машины и дополнительного ПО Не используются дополнительные порты AJAX — это модно :-)


Слайд 2

3 Почему prototype.js? Удобная и кроссбраузерная работа с AJAX’ом, DOM’ом Готовые расширения JavaScript-объектов ООП подход Самый популярный framework


Слайд 3

4 Базовый интерфейс чата Список сообщений Список пользователей Поле для сообщения Кнопка отправки сообщения


Слайд 4

5 Передача данных в AJAX-чате Что такое JSON и чем он хорош? Передача сериализованных объектов и массивов Native-поддержка в prototype.js JSON мало «весит» Вообще, есть и другие способы XML HTML-куски Текст HTTP-заголовки (реализация веб-сервисов)


Слайд 5

6 AJAX-запросы к серверу Список новых сообщений Список всех пользователей Отправка сообщения


Слайд 6

7 AJAX-запросы к серверу Список новых сообщений


Слайд 7

8 AJAX-запросы к серверу Список всех пользователей Получение дополнительных пользователей, нужных для отрисовки списка сообщений


Слайд 8

9 AJAX-запросы к серверу Отправка сообщения Объединение отправки и показа новых сообщений Буферизация сообщений


Слайд 9

10 Структура JavaScript-модулей /js/ /ajax/ chat.js (класс Chat + вспомогательные объекты) init.js («константы» + Ajax.Responders) /lib/ prototype.js (версия 1.5) utils.js (некоторые вспомогательные функции)


Слайд 10

11 JS-классы и объекты чата Ключевые используемые prototype.js-классы PeriodicalExecuter Ajax.Request Template Класс Chat Вспомогательные объекты ChatHelpers ChatAjaxHelpers ChatStrings


Слайд 11

12 JS-классы и объекты чата PeriodicalExecuter startListTimer: function(type){ if (typeof this[type + '_list_timer'] == 'undefined') this[type + '_list_timer'] = new PeriodicalExecuter(this[('get-' + type + '-list').camelize()].bind(this), this.options[type + '_updater_frequency']); else this[type + '_list_timer'].registerCallback(); }, stopListTimer: function(type){ if (typeof this[type + '_list_timer'] != 'undefined') this[type + '_list_timer'].stop(); }


Слайд 12

13 JS-классы и объекты чата Ajax.Request getMsgsList: function(){ this.stopListTimer('msgs'); new Ajax.Request( this.options.msgs_url, { method: 'get', parameters: 'room_id=' + this.room_id + '&stamp=' + this.stamp + ChatAjaxHelpers.addExtraAjaxParams(), onComplete: this.getMsgsListDone.bind(this), onFailure: ChatAjaxHelpers.handleAjaxFailure.bind(this, this.options.frontend_base_url) }); }


Слайд 13

14 JS-классы и объекты чата Template msg_default_tpl: new Template('<p class="#{css_class}"><span class="time">#{time}</span> <a href="#{profile_link}" target="_blank" title="Посмотреть профиль (в новом окне)">#{user_ico}</a><span class="#{username_css_class}">#{username}:</span> #{text}</p>'), msg_system_tpl: new Template('<p class="system-msg"><span class="time">#{time}</span> #{text}</p>'), msgListItemTemplate: function(vars, type){ var type = type || 'default'; return ChatHelpers['msg_' + type + '_tpl'].evaluate(vars); }


Слайд 14

15 JS-классы и объекты чата Класс Chat var Chat = new Class.create(); Chat.prototype = { initialize: function(room_id, msg_form, msg_input, msg_submit, msgs_list_div, users_list_div, user_login, options){ /* ... */ } };


Слайд 15

16 JS-классы и объекты чата Вспомогательные объекты ChatHelpers ChatAjaxHelpers ChatStrings var ChatStrings = { NA: 'N/A', TO: ' > ' }


Слайд 16

17 Практические приемы Инициализация настроек класса (options) Приватные данные в классе Борьба с кэшированием AJAX-запросов windows-1251 вместо UTF


Слайд 17

18 Tip: инициализация настроек this.options = { msgs_url: '/ajax/chat/data.html', msg_url: '/ajax/chat/msg.html', users_url: '/ajax/chat/users.html', frontend_base_url: '/chat/?room_id=0', msgs_updater_frequency: 5, users_updater_frequency: 20, max_msgs_in_list: 100, max_chars_in_username: 20 }; Object.extend(this.options, options || {});


Слайд 18

19 Tip: приватные данные var _users_open_cache = []; this.isInUsersOpenCache = function(user_id){ return (_users_open_cache.indexOf(user_id) >= 0); } this.usersOpenCacheAdd = function(user_id){ if (!this.isInUsersOpenCache(user_id)) _users_open_cache.push(user_id); } this.usersOpenCacheDelete = function(user_id){ _users_open_cache = _users_open_cache.without(user_id); }


Слайд 19

20 Tip: борьба с кэшированием var ChatAjaxHelpers = { /* ... */ addExtraAjaxParams: function(){ return '&rand=' + Math.random(); } , /* ... */ }


Слайд 20

21 Tip: windows-1251 вместо UTF window.encodeURIComponent = function(str){ var trans = []; for (var i = 0x410; i <= 0x44F; i++) trans[i] = i - 0x350; // А-Яа-я trans[0x401] = 0xA8; // Ё trans[0x451] = 0xB8; // ё var ret = []; for (var i = 0; i < str.length; i++){ var n = str.charCodeAt(i); if (typeof trans[n] != 'undefined') n = trans[n]; if (n <= 0xFF) ret.push(n); } return escape(String.fromCharCode.apply(null, ret)).replace(/\+/g, '%2B'); // + } window.decodeURIComponent = function(str){ return unescape(str); }


Слайд 21

22 Отладка чата Обработка исключений и AJAX-ошибок Объект Ajax.Responders Методы ChatAjaxHelpers.handleAjaxFailure и ChatAjaxHelpers.evalJsonResponse Firebug! Firebug! Firebug!


Слайд 22

23 Ajax.Responders var ajaxGlobalHandlers = { onException: function(t, e){ if (typeof DEBUG != 'undefined' && DEBUG){ var error_info = $H(e); var s = ''; error_info.each(function(pair){ s += pair.key + ' = "' + pair.value + '"\n'; }); alert(s); } } }; Ajax.Responders.register(ajaxGlobalHandlers);


Слайд 23

24 ChatAjaxHelpers.handleAjaxFailure var ChatAjaxHelpers = { /* ... */ handleAjaxFailure: function(frontend_base_url, request){ if (typeof DEBUG != 'undefined' && DEBUG) alert('Error: ' + request.status + ' -- ' + request.statusText); else if (request.status == 412) location.reload(); // Precondition Failed else location.href = frontend_base_url; } }


Слайд 24

25 ChatAjaxHelpers.evalJsonResponse var ChatAjaxHelpers = { /* ... */ evalJsonResponse: function(json_str){ var data = null; try{ data = eval('(' + json_str + ')'); }catch(e){ if (typeof DEBUG != 'undefined' && DEBUG) throw {message: 'JSON data is invalid!'}; } return data; } }


Слайд 25

26 Вопросы ?


Слайд 26

27 Что интересного на сервере? Крутится Perl-демон Клиент делает запросы по HTTP, через AJAX Демон «узнает» клиента по сессионной куке В ответ на любой из запросов демон отдает текстовый ответ в формате JSON JavaScript-модули gzip’уются Не стоит особо беспокоиться о большом размере модулей


×

HTML:





Ссылка: