Архитектура HP SharedX
Установление и поддержка соединений
Управление разделяемыми окнами
Управление вводом
Эффективность разделения приложений
Ограничения
Литература

Whitebeard - компонент НР SharedX


Система HP SharedX, разработанная компанией Hewlett-Packard, расширяет ставшую промышленным стандартом оконную систему Х Window System. Она позволяет организовать коллективное использование географически разделенными пользователями Х-приложений. Пользователи HP SharedX получают возможность совместно использовать информацию, находясь при этом в совершенно разных местах. Возможность совместного, в реальном времени, использования информации способствует значительному увеличению продуктивности.

Для начала приведем два примера. Администратор сети, включающей географически разбросанные узлы, в случае, если пользователь одного из узлов столкнется с той или иной проблемой, может с помощью HP SharedX создать общее с пользовательским компьютером окно. Благодаря ему администратор, не покидая своего рабочего места, получит возможность увидеть и диагностировать возникшую проблему. Пользователь же может наблюдать за действиями администратора.

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

HP SharedX основывается на Х Window, оконной системе, прозрачной относительно сети и предназначенной для использования в неоднородных вычислительных средах. Х Window System основана на модели "клиент/сервер". Клиенты (или Х-приложения) осуществляют доступы к дисплею только с помощью Х-сервера, управляющего ресурсами дисплея. Клиент и сервер обмениваются информацией посредством Х-протокола. Х-приложения, выполняющиеся на одном компьютере, могут отображаться на дисплее другого. Допускается использование разнородной аппаратуры различных поставщиков: от нее требуется лишь точное выполнение стандартного Х-протокола.

HP SharedX перенаправляет поток Х-протокола на несколько дисплеев, обеспечивая одновременное отображение одного Х-приложения на многих компьютерах. Важно, что для разделения существующих Х-приложений в них не требуется вносить какие-либо изменения. Компьютер, получающий разделяемое приложение, не требует никаких модификаций или установки специального программного обеспечения; получатели разделяемого приложения могут взаимодействовать с ним точно так же, как и его отправитель.

Архитектура HP SharedX

HP SharedX состоит из трех компонентов: интерфейса пользователя (называемого также коннектором), сервиса получателя и расширения Х-сервера. Коннектор осуществляет контроль отправителя за разделяемыми и неразделяемыми окнами, разрешает и запрещает получателю ввод, отображает статус разделения и т.д.

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

Расширение Х-сервера - механизм низкого уровня, в функции которого входит разделение окон, их обновление и мультиплексирование ввода от многих пользователей.

Сеанс разделения окон начинается с того момента, когда некоторый пользователь специфицирует получателя и указывает пиктограмму Share в окне коннектора HP SharedX. После этого отправитель выбирает разделяемое окно, нажав кнопку мыши над требуемым окном.

Перечислим следующие шаги:

1. Коннектор посылает по сети сообщение сервису получателя. Сервис получателя HP SharedX выводит на дисплее окно с запросом пользователю получающей системы о приеме разделяемого окна от отправителя.

2. Получатель возвращает коннектору ответ: "Да" или "Нет". В случае отрицательного ответа, отправитель информируется о том, что ему отказано в доступе к машине получателя.

3. Если ответ положительный, коннектор посылает специальный запрос Х-протокола о разделении окна Х-серверу отправителя. Х-сервер распознает этот запрос как предназначенный для расширения HP SharedX и вызывает соответствующую функцию для его обработки.

4. Расширение HP SharedX открывает сетевое соединение с Х-сервером получателя с помощью специального вызова библиотеки Xlib.

5. Расширение HP SharedX создает окна на экране получателя, соответствующие окнам на экране отправителя.

6. Х-сервер получателя посылает запрос на перерисовку вновь созданных окон.

7. Приложение отвечает на этот запрос перерисовкой содержимого всех своих окон. Запросы рисования Х-протокола для перерисовки окон выполняют, как обычно в локальном случае, Х-серверы отправителя, но поскольку приложение теперь разделяется, протокол отображается получателю. Таким образом, отправитель обновляет окна получателя в начале процесса разделения. В этот момент у получателя нет в наличии ни одного из ресурсов (графические контексты, шрифты и т.п.). Ресурсы получателя создаются по мере необходимости, то есть в момент их первого использования, а не тогда, когда они создаются разделяемым приложением.

После завершения перерисовки соединение установлено. С этого момента оба дисплея синхронизируются посредством отправки каждому серверу эквивалентных сообщений Х-протокола. Рассмотрим компоненты архитектуры HP SharedX подробнее.

Коннектор

Коннектор - это приложение Х Window, выполняющее все управляющей функции, необходимые для установления и контроля за разделением приложений. Окно коннектора содержит несколько полезных инструментов.

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

Разделяемый указатель(так называемый телепойнтер) служит для указания областей разделяемых приложений во время совместной работы.

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

Различные уровни диалоговой информации. Например, в начале работы в HP SharedX устанавливается уровень диалога Normal, что дает пользователю полную статусную информацию о разделяемом приложении. Когда пользователь устанавливает уровень диалога Experienced, диагностируются только критические ошибки.

Сервис получателя

Коннектор, получая запрос на разделение, делает попытку вызвать программу сервиса получателя на компьютере получателя. Если такая программа присутствует, она выводит на дисплее получателя окно диалога, которое сообщает пользователю, что отправитель хочет совместно использовать окно, и запрашивает ответ: "Да" или "Нет". Если ответ положительный, сервис получателя предоставит доступ к дисплею получателя для разделения. В противном случае коннектор выведет на экран отправителя сообщение об отказе в доступе.

Если сервис получателя отсутствует, коннектор попытается осуществить разделение с машиной получателя.

После того как HP SharedX разделил окна с получателем, сервису получателя дается указание устранить доступ к дисплею со стороны отправителя. Это предотвращает несанкционированные связи других процессов на компьютере отправителя с дисплеем получателя.

Расширение НР SharedX

Расширение HP SharedX составляют программы нижнего уровня для перехвата потоков данных, входящих и выходящих из Х-сервера во время сеанса разделения. Эти программы мультиплексируют ввод множества получателей и гарантируют, что дисплеи получателей модифицируются надлежащим образом.

Существуют четыре различные архитектуры, реализующие разделение приложений в среде Х Windows. Каждая из них имеет свои сильные и слабые стороны. При выборе архитектуры считалось необходимым отсутствие каких-либо изменений в приложении и базовом Х-сервере. Для этого требуется определенный интерфейсный механизм между приложениями и Х-сервером.

До сих пор наиболее популярной архитектурой для разделения окон в Х Window была архитектура с центральным псевдосервером. В этой архитектуре между разделяемыми приложениями и Х-сервером размещается процесс, отвечающий за разбиение выходного потока и объединение входных потоков данных. Такая архитектура наиболее гибкая, но дополнительный процесс порождает проблемы эффективности даже для неразделенных приложений.

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

Библиотека разделения переносит задачу разбиения выходного и объединения входных потоков из псевдосервера в библиотеку Х-функций (xlib), связанную с приложением. Удаление процесса псевдосервера повышает эффективность, однако такая система не может гарантировать разделяемость приложений либо из-за того, что они не связаны со специальной библиотекой, либо вследствие того, что они выполняются на машине в сети, не имеющей библиотеки разделения.

HP SharedX использует интегрированную архитектуру разделения, в которой происходит разбиение и объединение потоков данных в Х-сервер отправителя. Такая архитектура гарантирует разделяемость всех приложений, исключая при этом процесс псевдосервера.

Расширение HP SharedX имеет ряд преимуществ:

  • любое Х-приложение может разделяться в любой момент;
  • для неразделяемых приложений эффективность не снижается;
  • оптимизируется эффективность разделения, так как информация о состоянии Х-сервера непосредственно доступна механизму разделения (в других архитектурах приходится запрашивать эту информацию по сети, замедляя этим сам процесс разделения).
  • Основным недостатком архитектуры HP SharedX является необходимость модифицировать Х-сервер.

    Несмотря на различия между рассмотренными архитектурами, основы разделения приложений одинаковы для каждой из них (за исключением архитектуры копирования):

  • создание экземпляров окон на дисплеях получателей;
  • отображение запросов приложения каждому получателю;
  • установка соответствия между ресурсами на машине отправителя и ресурсами на машине получателя;
  • объединение входных событий от многих Х-серверов в единый поток и возвращение информации приложению.
  • Ниже будут рассмотрены подробнее некоторые проблемы разделения приложений и их решение в рамках архитектуры HP SharedX.

    Установление и поддержка соединений

    После того как получателю отправлен запрос о разделении, HP SharedX устанавливает Х-соединение с Х-сервером получателя. Это соединение позволяет управлять разделяемыми окнами, перенаправлять запросы изображения и принимать ввод получателя. Дисплейное соединение выполняется с использованием библиотеки Xlib.

    Xlib - это библиотека функций, используемая всеми Х-клиентами. Эти функции формируют запросы протокола, образующие пакеты Х-протокола, посылаемые по дисплейному соединению Х-серверу для создания окон, вывода в них изображения и т.д. Хотя расширение HP SharedX находится в Х-сервере отправителя, оно связывается с Х-сервером получателя, используя Xlib. Таким образом, Х-сервер отправителя выглядит для Х-сервера получателя точно так же, как любой другой Х-клиент.

    Однако расширение HP SharedX имеет ряд особенностей, отличающих его от других Х-клиентов. Поэтому в Xlib потребовалось внести некоторые изменения:

  • механизм восстановления при разрыве дисплейного соединения;
  • обработчик тайм-аутов;
  • механизм определения причины сбоя в дисплейном соединении.
  • В Х Window программы, теряющие соединение с Х-сервером, как правило, выдают сообщение об ошибке и прерывают работу. Действительно, для большинства Х-программ соединение необходимо. Однако это не так для Х-сервера отправителя, который и при отсутствии соединения с Х-сервером получателя имеет достаточно работы. Отсюда вытекает необходимость создания механизма восстановления при разрыве дисплейного соединения. В HP SharedX модифицирована библиотечная функция XIOError_Handler, вызываемая при разрыве соединения. Версия этой функции в HP SharedX очищает структуры данных, посылает сообщение в интерфейс пользователя и передает управление Х-серверу для продолжения работы.

    По ряду причин может возникнуть ситуация, когда удаленный Х-сервер не отвечает. Например, другая программа имеет исключительный доступ к Х-серверу, перегружая сеть между двумя компьютерами, либо Х-сервер получателя загружен обработкой запросов других клиентов. В каждом из этих случаев обычные Х-программы неопределенное время ожидают, пока их запросы не будут обработаны. Такое поведение для Х-сервера отправителя нежелательно, поэтому в HP SharedX в xlib добавлен обработчик тайм-аутов. После 30 секунд ожидания SharedX закрывает дисплейное соединение и сообщает отправителю, что получатель не отвечает.

    Последнее изменение в библиотеке Xlib обрабатывает сбои в установке Х-соединения. Обычно в таких случаях программе не сообщается о причине сбоя. В SharedX создан механизм, позволяющий определить причину и передать соответствующую информацию пользователю. Такая информация упрощает диагностику проблем в процессе разделения окон.

    Управление разделяемыми окнами

    Когда пользователь выбирает приложение, предназначаемое для совместного использования, SharedX следует отобрать группу окон, наилучшим образом представляющих данное приложение, для отправки на дисплей получателя. Большинство приложений состоит из одной программы, имеющей одно соединение с Х-сервером. В таких случаях выбор прост. Однако приложение может состоять более чем из одной программы (например, инструментальная среда HP SoftBench), либо одна программа может использовать несколько окон, которые не следует объединять (например, менеджер файлов HP VUE способен отображать каталоги в разные окна). Пользователи HP SoftBench могут совместно использовать окна отладки и анализа программы, в то время как пользователи менеджера файлов обычно запрашивают разделение только одного окна.

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

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

    При выборе окон для разделения HP SharedX делает два предположения:

  • все окна верхнего уровня, принадлежащие одному дисплейному соединению, относятся к одному приложению;
  • все окна-потомки разделяемого окна верхнего уровня должны разделяться с этим окном.
  • Используя эти предположения, в случае разделения окна программы-менеджера файлов HP VUE, SharedX отправит получателю все окна менеджера файлов. Для разделения отдельных окон пользователь имеет в меню опцию выбора Share Alone. Кроме того, SharedX может конфигурироваться таким образом, чтобы по-разному реагировать на кнопку Share для разных приложений. Для большинства приложений используется SharedX, сконфигурированная так, чтобы разделять только выбранное окно верхнего уровня и его потомков.

    Проблема одновременного разделения окон для нескольких программ в рамках одного приложения (как в случае HP SoftBench) не решена непосредственно. SharedX не обеспечивает простого механизма группировки окон различных программ. Обычно для таких приложений пользователю приходится вручную разделять все требуемые окна.

    Управление вводом

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

    Существуют два метода объединения ввода при разделении приложений: передача права доступа и "свободно-для-всех".

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

    Метод "свободно-для-всех" разрешает ввод любому пользователю без явного действия, но при этом не исключено перемешивание ввода от разных пользователей.

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

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

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

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

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

    Ресурсы дисплея - это цвета, таблицы пикселов, графические контексты и шрифты. Для выделения этих ресурсов система SharedX использует следующую схему: ресурсы дисплея выделяются, только когда они необходимы для выполнения запросов изображения. Это минимизирует начальное время разделения и контакты с компьютером получателя. Например, разделяемое приложение выделяет большую таблицу пикселов, отображаемую только при возникновении некоторых ошибочных ситуаций. Если за время сеанса разделения эти ошибки не произойдут, создание экземпляра этой таблицы пикселов на машине получателя было бы простой тратой времени и ресурсов.

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

    Нарисовать линию на локальном дисплее;
    Для каждого удаленного экземпляра окна
    begin
     if удаленный экземпляр графического контекста уже выделен,
     использовать этот экземпляр,
    e1se
     Выделить новый удаленный графический контекст и отобразить его в локальный графический 
    контекст и отобразить его в локальный графический контекст;
     Нарисовать линию в экземпляре окна с экземпляром графического контекста;
    end;

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

    Управление такими ресурсами, как графические контексты и окна, осуществляется достаточно просто. Сложнее обстоит дело с управлением цветами. SharedX стремится выводить идентичные образы во всех разделяемых окнах. Это требует отображения цветов с дисплея отправителя на дисплей получателя. Если точное воспроизведение цветов на удаленном дисплее невозможно, выбираются цвета, наиболее близкие к исходным.

    Непростую задачу приходится решать и при установлении соответствия между шрифтами, используемыми в разделяемых окнах. Текст вводится Х-приложением с помощью шрифта, который выбирает пользователь Х Window System. X-Window не имеет стандартных шрифтов, и каждый Х-сервер может поддерживать набор шрифтов, отличный от других.

    При разделении приложения важно поддерживать соответетвие между шрифтами для вывода текста у отправителя и получателя. Опишем подробнее используемый алгоритм.

    В Х Window каждый шрифт имеет имя и характеристики. Шрифт загружается либо по имени, либо по характеристикам с использованием формата XLFD (Х Logical Font Description - Логическое Описание Шрифта Х). Сначала делается попытка установить соответствие между шрифтами по имени, поскольку считается маловероятным, что шрифты с одинаковым именем будут различаться. Если шрифт с тем же именем недоступен на машине получателя, соответствие устанавливается по характеристикам шрифтов.

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

    Эффективность разделения приложений

    На эффективность приложений в системе SharedX влияет ряд факторов:

  • характеристики сетевого соединения;
  • эффективность рабочих станций, участвующих в сеансе разделения;
  • само разделяемое приложение.
  • Эффективность сетевого соединения зависит от трех факторов: пропускной способности сети, задержек линии связи и загрузки сети. Увеличение загрузки приблизительно эквивалентно снижению пропускной способности. Задержки линии связи имеют значение для процесса разделения в глобальной сети. Время модификации экрана растет пропорционально задержкам линии.

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

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

    Если окна приложения могут менять размер, отправитель повысит эффективность, уменьшив окна. Если приложение выполняется слишком медленно при разделении, отправитель может скопировать ее части в Whiteboard и разделить уже Whiteboard.

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

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

    - самые быстрые машины должны соединяться по схеме "связывание с первым", а медленные машины следует организовать в дерево разделения;

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

    Ограничения

    Не для всех приложений с помощью SharedX можно гарантировать правильное разделение. Например, на рабочих станциях Hewlett-Packard приложения осуществляют вывод на экран дисплея одним из двух способов: с помощью Х-сервера, используя Х-протокол, или непосредственно, используя прямой аппаратный доступ DHA. Так как функционирование SharedX связано с переназначением Х-протокола на дисплей получателя, DHA-программы нельзя разделять непосредственно. Статические изображения из приложений, использующих DHA, могут разделяться посредством копирования их окон в Whiteboard.

    Но и не всякое Х-приложение может разделяться должным образом. Например, аудиоприложение системы мультимедиа НР MPower использует Х-протокол для отображения панели управления, а для воспроизведения звука использует специальный аудиосервер. С панелью управления все будет в порядке, однако когда получатель нажмет кнопку Play, звук появится только у отправителя, воспроизведенный с помощью его аудиосервера.

    Другой пример - приложения, использующие расширения стандартных возможностей Х Window System. Базовый Х-протокол является стандартом для всех Х-серверов, но Х-расширения для разных реализаций Х-сервера различны. Поскольку SharedX перенаправляет только базовый Х-протокол, разделение приложений, использующих Х-расширения, может быть связано с определенными ограничениями. Например, если с помощью Х-расширения ввода приложение использует устройства ввода, отличные от клавиатуры и мыши, получатель увидит копию окна, но не сможет взаимодействовать с приложениями с помощью этих дополнительных устройств.


    Литература

    D. Garfinkel, В. Welti, Т. Yip. HP SharedX. А Tool for Real-Time Collaboration. - Hewlett-Packard Journal, April 1994, vo. 45, n. 2.


    Whitebeard - компонент НР SharedX

    Whiteboard, дополнение к системе SharedX, - это Х-приложение, позволяющее аннотировать графические изображения в коллективных приложениях.

    Основное свойство Whiteboard, которое хотелась бы подчеркнуть, заключается в возможности стирать аннотации, сделанные на изображении, не разрушая самого изображения. Whiteboard поддерживает концепцию стираемого и нестираемого уровней. Загружаемое в Whiteboard изображение относится к нестираемому уровню. Аннотации выполняются на стираемом уровне и могут быть отменены

    Другая возможность, предоставляемая Whiteboard, - копирование любого фрагмента пользовательского экрана и вставка его в область рисования Whiteboard.

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

    Поделитесь материалом с коллегами и друзьями