Чтение онлайн

на главную - закладки

Жанры

Программирование на языке Ruby
Шрифт:

Клиент:

• устанавливает соединение с сервером;

• привязывает локальный объект к удаленному экземпляру сервера;

• посылает сообщения серверу и получает ответы.

Метод класса

start_service
отвечает за запуск TCP-сервера, прослушивающего указанный порт. Он принимает два параметра: URI (универсальный идентификатор ресурса), задающий порт (если он равен
nil
, то порт выбирается динамически), и объект, к которому мы хотим привязаться. Этот объект будет доступен удаленному клиенту, который сможет вызывать его методы, как если бы объект был локальным.

require "drb"

myobj = MyServer.new

DRb.start_service("druby://:1234", myobj) # Порт 1234.

# ...

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

uri
.

DRb.start_service(nil, myobj)

myURI = DRb.uri # "druby://hal9000:2001"

Поскольку

drb
—многопоточная программа, любое серверное приложение должно выполнять
join
в потоке сервера (чтобы не дать приложению завершиться преждевременно и тем самым уничтожить выполняющийся поток).

# Предотвратить преждевременный выход.

DRb.thread.join

На стороне клиента мы вызываем метод

start_service
без параметров и с помощью класса
DRbObject
создаем локальный объект, соответствующий удаленному. Обычно первым параметром методу
DRbObject.new
передается
nil
.

require "drb"

DRb.start_service

obj = DRbObject.new(nil, "druby://hal9000:2001")

# Сообщения, передаваемые obj, перенаправляются

# удаленному объекту на стороне сервера...

Следует подчеркнуть, что на стороне сервера привязка осуществляется к единственному объекту, который должен отвечать на все получаемые запросы. Если клиентов несколько, то объект должен быть безопасным относительно потоков, чтобы не оказаться в некорректном состоянии. (Для совсем простых или узкоспециализированных приложений это может быть и необязательно.)

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

Mutex
. (Подробнее о потоках и синхронизации рассказывается в главе 13.)

Скажем хотя бы несколько слов о безопасности. Ведь не всегда желательно, чтобы с вашим сервером мог соединяться кто угодно. Помешать им пытаться вы не можете, зато можете сделать такие попытки безуспешными.

В программе

drb
есть понятие списка контроля доступа (ACL). Это не что иное, как списки клиентов (или категорий клиентов), которым явно разрешен (или запрещен) доступ.

Приведем пример. Для создания нового списка ACL мы воспользуемся классом

ACL
, которому передадим один или два параметра.

Второй (необязательный) параметр метода

ACL.new
служит для ответа на вопрос: «Мы запрещаем доступ всем клиентам, кроме некоторых, или, наоборот, разрешаем доступ всем клиентам, кроме некоторых?» По умолчанию принимается первый вариант, который обозначается константой
DENY_ALLOW
равной 0. Второй режим обозначается
ALLOW_DENY
равной 1.

Первый параметр

ACL.new
представляет собой обычный массив строк, которые идут парами. Первая строка в паре должна быть равна
"deny"
или
"allow"
, вторая описывает одного клиента или группу клиентов (по имени или по адресу):

require "drb/acl"

acl = ACL.new( %w[ deny all

 allow 192.168.0.*

 allow 210.251.121.214

 allow localhost] )

Первая пара в этом примере, строго говоря, излишня, но проясняет смысл всей конструкции.

А как используются ACL? Метод

install_acl
приводит ACL в действие. Его необходимо вызывать перед обращением к
start_service
, иначе он не возымеет эффекта.

# Продолжение примера...

DRb.install_acl(acl)

DRb.start_service(nil, some_object)

# ...

Теперь, после запуска сервиса любой неавторизованный запрос на соединение приведет к исключению

RuntimeError
.

Это, конечно, не все, что можно сказать о библиотеке

drb
. Но для обзора вполне достаточно. В следующем разделе мы рассмотрим простой drb-сервер и drb-клиент, близкие к реальным программам. А затем поговорим о программах Rinda и Ring.

20.2. Пример: эмуляция биржевой ленты

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

Но мы добавили одну тонкость. Не желая следить за малейшими колебаниями цен, мы реализовали модуль

Observer
, который позволяет подписаться на информационный канал. Клиент следит за поступающими сведениями и предупреждает нас, когда изменение цены превысит заданный порог.

Сначала рассмотрим модуль

DrbObservable
. Это прямолинейная реализация паттерна
Observer
(Наблюдатель), описанного в замечательной книге Э. Гаммы, Р. Хелма, Р. Джонсона и Дж. Влиссидеса «Паттерны проектирования» (см. сноску в разделе 12.3.1). Еще этот паттерн называют «Издатель-Подписчик».

Поделиться:
Популярные книги

Светлая тьма. Советник

Шмаков Алексей Семенович
6. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Светлая тьма. Советник

Точка Бифуркации VIII

Смит Дейлор
8. ТБ
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Точка Бифуркации VIII

Кодекс Охотника. Книга XV

Винокуров Юрий
15. Кодекс Охотника
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XV

Бастард

Майерс Александр
1. Династия
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард

Моя простая курортная жизнь 4

Блум М.
4. Моя простая курортная жизнь
Любовные романы:
эро литература
5.00
рейтинг книги
Моя простая курортная жизнь 4

Я до сих пор князь. Книга XXII

Дрейк Сириус
22. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я до сих пор князь. Книга XXII

На цепи

Уваров
1. На цепи
Старинная литература:
прочая старинная литература
5.00
рейтинг книги
На цепи

Черный Маг Императора 18

Герда Александр
18. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 18

Перешагнуть пропасть

Муравьёв Константин Николаевич
1. Перешагнуть пропасть
Фантастика:
боевая фантастика
космическая фантастика
8.38
рейтинг книги
Перешагнуть пропасть

Воронцов. Перезагрузка. Книга 3

Тарасов Ник
3. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фэнтези
фантастика: прочее
6.00
рейтинг книги
Воронцов. Перезагрузка. Книга 3

Лекарь Империи 9

Карелин Сергей Витальевич
9. Лекарь Империи
Фантастика:
городское фэнтези
аниме
боевая фантастика
5.00
рейтинг книги
Лекарь Империи 9

Кай из рода красных драконов 2

Бэд Кристиан
2. Красная кость
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Кай из рода красных драконов 2

Как я строил магическую империю 5

Зубов Константин
5. Как я строил магическую империю
Фантастика:
попаданцы
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 5

Идеальный мир для Лекаря 12

Сапфир Олег
12. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 12