Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
14
Добавлен:
28.03.2016
Размер:
574.45 Кб
Скачать

21

02070743.00569-01 81 01

Багатообіцяючим виглядає проект InstantRails (http://instantrails.rubvforge.org). Це єдиний пакет, Ruby, що містить, Rails, MYSQL і Apache, причому всі продукти вже конфігуровані і готові до роботи.

На платформі OS/X є еквівалентний проект Locomotive. Це досить зріле і добре працююче середовище для розгортання Rails «одним клацанням».

Існує також RadRails – інтегроване середовище розробки для Rails,

надбудованою над Eclipse, що підтримує управління версіями, відладку,

сервери WEBrick, майстер генерації коду, синтаксичне підсвічування,

інструменти для роботи з даними і багато що інше. Цей пакет повинен працювати на всіх платформах, де працює сам Eclipse.

Важливо також розуміти, що таке модулі Rails, що підключаються

(plugins). Це невеликі автономні програми, які модифікують поведінку

ActiveRecord або Rails. Їх нескладно писати і розгортати. Існують сотні невеликих модулів, що підключаються, займаються аутентифікацією,

генерацією GUID, інтернаціоналізацією, підтримкою CSS і так далі.

2.7. Ruby і Web-сервер

На сьогоднішній день одним з найпопулярніших Web-серверов є Apache.

Ще одна корисна можливість на стороні сервера – вбудований Ruby; цю технологію підтримують інструменти erb і eruby. Вони дозволяють вбудовувати код на Ruby в текст сторінки (зазвичай HTML або XML), унаслідок чого дані можна вставляти динамічно.

Деякі розробники реалізували Web-сервери, написані цілком на Ruby.

Природно виникає питання: навіщо писати новий Web-сервер, коли їх вже і так існує немало – узяти хоч би той же Apache?

По-перше, є ситуації, коли бажано мати спеціалізований Web-сервер,

наприклад ради нестандартного способу обробки сторінок, коли можна пожертвувати функціональністю заради швидкості, або для автоматичної трансляції спеціальної розмітки в HTML.

41

22

02070743.00569-01 81 01

По-друге, може виникнути бажання по експериментувати з поведінкою сервера і його взаємодією із зовнішнім кодом, наприклад з CGI-програмами.

Можливо, у вас є якісь ідеї відносно створення сервера застосувань і середовища розробки на стороні сервера.

По-третє, інколи буває розумно вбудувати Web-сервер в інше застосування. До цієї можливості удаються розробники, що бажають надати функціональність програмної системи зовнішньому світу; протокол HTTP

простий і чітко визначений, а Web-браузеры як клієнти є всюди. Цей прийом можна навіть використовувати для видаленої відладки, якщо система часто оновлює свій внутрішній стан і робить його доступним вбудованому серверу.

І остання причина полягає в тому, що невеликий автономний Web-сервер може спростити розгортання і конфігурацію. Наприклад, перезапустити сервер для застосування Rails набагато простіше, якщо в цій якості виступає WEBrick,

а не Apache [18].

2.7.1. Модуль mod_ruby

Зазвичай, якщо CGI-сценарий пишеться мовою, що інтерпретується, то при кожному запиті завантажується новий екземпляр інтерпретатора. Це дорого обходиться з точки зору вжитку ресурсів сервера і часу виконання.

Сервер Apache вирішує цю проблему шляхом створення завантажуваних модулів, які, по суті, стають частиною сервера. Вони завантажуються динамічно в міру необхідності і стають загальними для всіх залежних від них сценаріїв. Одним з таких модулів є mod_ruby.

Модуль mod_ruby реалізує декілька директив Apache, зокрема:

RubyRequire визначає одну або декілька необхідних бібліотек;

RubyHandler визначає обробник для об'єкту Ruby;

RubyPassEnv визначає імена змінних оточення, передаваних сценаріям;

RubySetEnv встановлює змінні оточення;

RubyTimeOut задає величину тайм-ауту для Ruby-сценаріїв;

RubySafeLevel задає рівень безпеки SSAFE;

42

23

02070743.00569-01 81 01

• RubyKanjiCode встановлює кодування символів для Ruby.

До складу пакету входять також класи і модулі Ruby для взаємодії з

Apache. Модуль Apache (у сенсі, прийнятому в Ruby) включає декілька функцій, наприклад server_version і unescape_url; там же визначені класи

Request і Table.

Apache::Request – це обгортка для типа даних request_rec, що визначає такі методи, як request_method, content_type, readlines і так далі Клас Apache::Table –

обгортка для типа даних table; він визначає, серед інших, методи get, add і each.

Є детальні інструкції по компіляції і установці пакету mod_ruby.

Звернетеся до тієї, що поставляється в комплекті з ним документація (або еквівалентній інформації в Мережі [9]).

2.2.2. Сервер WEBrick

WEBrick – це бібліотека для створення повноцінного HTTP-сервера. WEBrick майже нічого не знає про деталі Web-приложений. Він не

розуміє, що таке сеанс користувача і інші тонкощі. Він оперує лише сервлетами, що працюють незалежно один від одного. Якщо вам необхідна функціональність більш високого рівня, пошукайте іншу бібліотеку (можливо,

надбудову над WEBrick на кшталт IOWA або Tofu) або напишіть свою власну

[3].

Робота з WEBrick зводиться до такої послідовності дій: створюється екземпляр сервера; визначаються обробники монтування і обробники сигналів;

запускається сервер.

Як працює сервлет? Ідея в тому, аби визначити метод для кожної підтримуваної HTTP-операции, наприклад do_GET для запитів типа GET. Якщо ви звиклися писати програми, що звертаються до сервера, то тепер доведеться встати на протилежну точку зору, адже ваш код стає частиною Web-сервера. Ви не отримуєте помилку з кодом 404, а самі посилаєте цей код.

43

24

02070743.00569-01 81 01

На щастя, не потрібно писати сервлети для кожної крихітної задачки, яку повинен виконувати WEBrick. У нього є декілька своїх зумовлених сервлетов

(все в просторі імен WEBrick: :HTTPServlet):

FileHandler

ProcHandler

CGIHandler

ERBHandler

WEBrick має в своєму розпорядженні і багато інших можливостей,

наприклад точками підключення для виконання додаткових завдань (скажімо,

запуску якої-небудь програми при старті). Є також розвинені засоби протоколювання, аутентифікації по протоколу HTTP і так далі [3]

2.7.3. Сервер Mongrel

Основна мета цього сервера – підвищити продуктивність в порівнянні з

WEBrick. У даному відношенні він добився значних успіхів і працює у багато разів швидше

Mongrel часто використовують у поєднанні з Rails, а документація місцями орієнтована на Rails. Але жорсткої прив'язки до Rails немає – сервер може працювати і в інших контекстах. Mongrel – швидше, застосування, тоді як

WEBrick більше нагадує бібліотеку. Багато в чому вони схожі, але порядок запуску і API розрізняються [4]. У багатьох випадках Mongrel можна запустити як застосування без написання якого-небудь коду. Він розуміє три основні команди: start, stop і restart. В команди start багато параметрів, що модифікують поведінку сервера, наприклад: --port portnum --log filename --daemonize і так далі. Аби отримати повний список, введіть таку команду:

mongrel_rails start –h

Запуск в стандартному режимі – це добре, але рано чи пізно виникне потреба в чомусь незвичайному. На цей випадок передбачені конфігураційні

44

25

02070743.00569-01 81 01

файли. Простий спосіб підготувати конфігураційний файл для Mongrel –

скористатися прапором –G. Наприклад, можна ввести такий командний рядок:

raongrel_rails start –G myconfig.yml –p 3000 –r /home/hal/docs

–1 my.log

Задані параметри будуть збережені (у форматі YAML) у файлі myconfig.yml (за наявності прапора –G сервер завершується відразу після створення конфігураційного файлу).

Для читання параметрів з конфігураційного файлу задайте прапор –C:

mongrel_rails start –С myconfig.yml

Не вживайте прапор –с разом з іншими. Він передбачає, що всі параметри знаходяться у вказаному файлі.

Mongrel пропонує API для тонкого налаштування поведінки сервера.

Прапор –S дозволяє задати ім'я сценарію, написаного з використанням цього

API, який є невеликою мовою наочної області (DSL – Domain-Specific Language). У документацію наведений приклад такого сценарію (який додає обробник для каталога, відмінного від поточного):

#Файл: config/mongrel.conf uri "/newstuff" :handler =>

DirHandler.new("/var/www/newstuff")

#Викликається такою командою:

#mongrel_rails start –S config/mongrel.conf

Якщо ви активно працюєте з Mongrel, то вас може зацікавити система

GemPlugin. Це, по суті, автозавантажувані gem-пакети, які стають «частиною»

Mongrel. Наприклад, модуль «Mongrel cluster» дозволяє легко управляти кластером серверів Mongrel.

45

26

02070743.00569-01 81 01

2.8. Особливості розробки алгоритмів для Ruby

Розглянемо на прикладі особливості розробки і реалізації алгоритмів для

Ruby. Для цього створимо сторінку з вікном введення і кнопкою «Зберегти»,

при натисненні на яку відбувається збереження тексту з вікна введення у файл notepad.txt. Введення здійснюється через браузер за адресою http://localhost:8080. Сервер запускатимемо на порт 8080. Тепер, власне, сама програма:

require 'webrick'

server = WEBrick::HTTPServer.new(:Port=>8080) server.mount_proc('/'){ |req, resp|

File.open('notepad.txt', 'w'){ |f| f.write(req.query["text"]) } if req.query["text"] resp['Content-Type']= 'text/html'

resp.body = %& <html><body><center><form method="post"> <textarea name="text" rows="4"

cols="40">#{IO.read('notepad.txt')}</textarea><br/>

<input type="submit" name="update" value="Сохранить"/> </form></center></body></html></nowiki>&

}

server.start

Розглянемо код детальніше:

require 'webrick' підключення бібліотеки WEBrick для побудови серверів (у тому числі і Web-сервер-серверів).

:Port=>8080 – асоціативний масив із значенем порту. Коли порт 80

зайнятий, доводиться шукати інший. Винятковою магічною силою порт 8080 не володіє. Тому, за бажання, його можна змінити на іншій.

server.mount_proc('/') – на віртуальну кореневу директорію ми вішаємо процедурний сервлет. Він займатиметься обробкою запиту на адресу http://localhost:8080/, тобто звернення до віртуальної кореневої директорії. Аби змінити запит, на який відгукуватиметься сервлет, досить замінити рядок '/' на

46

27

02070743.00569-01 81 01

іншу, наприклад '/notepad'. Тоді, адреса сервлета буде http://localhost:8080/notepad.

{ |req, resp| . } – процедурному (як і будь-якому іншому) сервлету передається в замикання дві змінні. Змінна req містить інформацію про запит

(який браузер запрошує, які змінні передаються і так далі), а за допомогою змінної resp формується відповідь (який тип інформації передається,

інформація для відображення і так далі).

. if req.query["text"] – постфіксний запис умовного оператора if.

Блок, перед if виконуватиметься лише у тому випадку, коли сервлету передаватиметься змінна text. Метод .query повертає асоціативний масив у вигляді {имя_переменной=>значение}.

File.open('notepad.txt', 'w'){|f| f.write(req.query["text"]) }

– відкриваємо файл notepad.txt для запису і пишемо туди значення змінної text

(передається сервлету в тілі запиту).

resp['Content-Type']= 'text/html' – встановлюємо типа передаваних нами даних. Зазвичай тип визначається по розширенню файлу, але процедурний сервлет про файл, а тим більше про його розширення, нічого не чув. Ось і доводиться вказувати типу передаваних даних через параметр

Content-Type.

resp.body = %& . & – за допомогою методу .body= ми передаємо HTML-

код як відповідь на запит. Сам HTML-код передається у вигляді рядка,

поміщеному в %& . &. Це альтернативний спосіб завдання рядка. Після символу % йде символ, який буде таким, що замикає (у нашому випадку & ).

Такий спосіб завдання рядка використовується у випадках, коли рядок містить багато лапок і апострофів (аби не займатися їх екрануванням).

server.start – за допомогою методу .start ми запускаємо Web-сервер.

Для того, щоб припинити роботу Web-сервера, треба його просто вивантажити. Це робиться за допомогою комбінації клавіш Ctrl+Break або

Ctrl+C.

47

28

02070743.00569-01 81 01

Вийшов трохи громіздкий опис, але це лише спочатку. Далі ми розглядатимемо лише зміни, а їх буде істотно менше.

Тепер приступимо до ERB. Це шаблонна бібліотека, яка дозволяє здійснювати вставку в довільний текст будь-якої Ruby-коду. Для цього є два основних тега:

<% . %> – Код усередині тега виконується. Під час обробки він замінюється на порожній рядок.

<%= . %> – Код усередині тега виконується. Результат останнього обчислення перетвориться в рядок і вставляється замість тега.

Обробка коду всередині тегів ERB йде лише під час обробки шаблону

(виклику методу .result).

ERB для прихильників РНР – це «PHP, лише на Ruby». Ця фраза володіє настільки магічною властивістю, що після неї співбесідникові все стає зрозумілим. Давайте поглянемо, як може виглядати наша програма в якій використовується ERB-шаблон:

require 'webrick' require 'erb'

server = WEBrick::HTTPServer.new(:Port=>8080) server.mount_proc('/'){ |req, resp|

File.open('notepad.txt', 'w'){ |f| f.write req.query["text"] } if req.query["text"]

resp['Content-Type']= 'text/html'

template = %& <html><body><center><form method="post"> <textarea name="text"

rows="4"cols="40"><%=IO.read('notepad.txt')%></textarea><br

/>

<input type="submit" name="update" value="Сохранить"/>

</form></center></body></html>&

resp.body = ERB.new(template).result

48

29

02070743.00569-01 81 01

}

server.start

Що змінилося? Змін небагато, але вони все ж є: require 'erb' – підключаємо бібліотеку ERB.

template = %& . <%=IO.read('notepad.txt')%> . & – створюємо змінну template і привласнюємо їй рядок, який за сумісництвом є ERB-

шаблоном. Усередині рядка можна відмітити тег <%= . %>, усередині якого здійснюється зчитування файлу notepad.txt. Результат зчитування буде вставлений замість тега <%= . %> під час обробки ERB-шаблона.

resp.body = ERB.new(template).result – створюємо об'єкт ERB і

передаємо туди підготовлений ERB-шаблон. Обробляємо його методом .result і

результуючий рядок передаємо методу .body =, який підставляє її як відповідь на запит.

І що ми отримуємо в результаті? Підключили «зайву» бібліотеку і створили «зайву» змінну? Не квапитимемося з виводами. Використання бібліотеки ERB дозволяє винести шаблон в зовнішній файл. Тим самим ми очищаємо Ruby-код від HTML-коду.

ERB-шаблон істотно псує красу нашої Ruby-коду. Тому, рішення винести шаблон в зовнішній файл сповна виправдане. Тим паче, що це дозволить нам правити ERB-шаблон окремо від програми. Більш того, внесені до шаблону зміни набиратимуть чинності без перезавантаження сервера.

Файл з ERB-шаблоном (index.html) виглядатиме таким чином:

<html>

<body>

<center>

<form method="post">

49

30

02070743.00569-01 81 01

<textarea name="text" rows="4" cols="40"><%=IO.read('notepad.txt')%></textarea><br/>

<input type="submit" name="update" value="Сохранить"

/>

</form>

</center>

</body>

</html>

Змінну шаблон ми прибираємо, а замість неї вставимо зчитування файлу з

ERB-шаблоном(index.html).

require 'webrick' require 'erb'

server = WEBrick::HTTPServer.new(:Port=>8080) server.mount_proc('/'){ |req, resp|

File.open('notepad.txt', 'w'){ |f| f.write req.query["text"] } if req.query["text"]

resp['Content-Type']= 'text/html'

resp.body = ERB.new(IO.read('index.html')).result

}

server.start

Зчого складається наша програма тепер?

1.notepad.rb. Програма-сервер. Назвати файл можна на власний розсуд.

Головне, аби працював. Містить логіку, яка здійснює конфігурацію і запуск

сервера.

50