Модифицированная версия исследовательского прототипа многоагентной системы для организации поиска данных по запросам в распределенной информационной системе TORIS – серверов.

Для информационной поддержки исследований и разработок в области топонимики был разработан тематический Web-сайт TORIS (TOponimic Research Information System, http://toris.krc.karelia.ru  ). 
Структура сайта включает следующие основные разделы: 
•	БАЗЫ ДАННЫХ (база данных, содержащая информацию о топонимах; библиографическая база данных по публикациям в области исследования топонимии); 
•	ФОРУМ для организации и проведения тематических электронных конференций; 
•	ЭЛЕКТРОННЫЕ ПУБЛИКАЦИИ для размещения электронных материалов по вопросам исследования топонимии; 
•	ССЫЛКИ на информационные ресурсы по топонимии в Интернет. 
Структура описания русской, прибалтийско-финской и саамской топонимии учитывает структурные, семантические и иные свойства топонима, а также экстралингвистические признаки объекта, именуемого данным топонимом. Это дает возможность специалистам ставить и решать ряд задач, связанных с выявлением субстратного слоя топонимии, его фонетических и морфологических особенностей, исследовать ареалы смешения топонимии и др. 
В плане дальнейшего развития этой работы нами рассматривается модель распределенной информационной системы, которая обладает следующими основными свойствами: 
•	система представляет собой совокупность распределенных в сети Интернет TORIS-серверов с интегрированными базами данных, расположенных в различных географических районах и связанных между собой сетями передачи данных; 
•	запросы пользователей к нужной информации осуществляются через Интернет с использованием стандартных программ-просмотрщиков (браузеров) путем обращения к базам данных системы по разработанным однородным интерфейсным формам. 
Традиционная технология процесса организации поиска информации в базах данных распределенной информационной системы предполагает персональное обращение пользователя по сети Интернет к каждому TORIS-серверу с запросом, формирование из полученных ответов сводного результата и его последующая обработка. Выполнение, в общем-то, рутинных операций может отнимать у специалистов достаточно много рабочего времени. В связи с этим становится актуальной задача разработки многоагентной системы для автоматизации процессов исполнения запросов в распределенной информационной системе, которая взяла бы на себя большую часть рутинных операций по организации поиска информации в базах данных системы TORIS-серверов. 

Рис. 1 Общая архитектура системы TORIS

Электронные
ящики
пользователей

A

A

A

I1

I2

I3

C

C

C

A

A

A

A

A

A

БД

БД

БД

Общую структуру системы TORIS можно представить следующим образом (рис.1). 
Архитектура и функции многоагентной системы

Для поиска информации в базах данных распределенной информационной системы TORIS нами была разработана многоагентная система (МАС), архитектура которой представлена на рис. 2. Все агенты, входящие в МАС, относятся к одному из следующих основных классов: 
1.	агенты-менеджеры, работающие на серверах и организующие процесс поиска; 
2.	интерфейсные агенты, осуществляющие взаимодействие с пользователем; 
3.	агенты-исполнители, отвечающие за определенную стадию поиска. 

Рис. 2 Архитектура многоагентной системы

Предполагается, что агенты расположены на разных серверах системы TORIS и взаимодействуют друг с другом при выполнении запроса, поступившего от пользователя.
В серверную часть МАС входят агенты: ControlAgent; SQLAgent и MailAgent, а в клиентскую часть - InterfaceAgent. Обмен сообщениями между агентами основан на протоколе TCP, а работа с базой данных осуществляется по протоколу JDBC. 
Основными функциями InterfaceAgent являются: 
•	регистрация пользователя на TORIS-сервере (в частности, фиксирование его e-mail); 
•	прием от пользователя запроса на поиск данных во ВСЕХ базах данных распределенной информационной системы TORIS и оказание ему помощи при формировании sql-запроса; 
•	установление связи с ControlAgent, передача ему запроса и электронного адреса пользователя. 
Основными функциями ControlAgent являются: 
•	прием от InterfaceAgent запросов на поиск данных в распределенной информационной системе; 
•	связь с другими серверами системы TORIS и передача им запросов; 
•	активизация SQLAgent для поиска требуемой информации в локальной базе данных; 
•	формирование ОБЩЕГО ОТВЕТА на запрос; 
•	активизация MailAgent для отправки ответа пользователю по электронной почте. 
Основными функциями SQLAgent являются: 
•	отбор данных в базе данных TORIS-сервера по запросу, полученному от ControlAgent; 
•	перекодировка информации, получаемой из БД; 
•	запись полученных данных в результирующий поток (файл, сокет). 
Функцией MailAgent является уведомление пользователя по электронной почте о том, что его запрос обработан и передача ему ссылки на ответ. 

 Принципы функционирования
Общая схема работы пользователя с МАС состоит в следующем. Пользователь обращается по сети Интернет к одному из TORIS-серверов распределенной информационной системы и с помощью интерфейсной формы МАС формирует запрос на поиск информации в базах данных этой системы. МАС автоматически осуществит поиск нужной ему информации на всех серверах системы, подготовит общий ответ на запрос и уведомит пользователя по электронной почте о полученном результате с указанием ссылки на него.
 
 Реализация многоагентной системы
Реализация многоагентной системы включала в себя две стадии:
1.	выявление агентов, входящих в систему, и разработка сценариев переговоров между агентами;
2.	программная реализация многоагентной системы.

2.4.1Разработка сценариев переговоров
В качестве языка взаимодействия агентов был взят язык KQML, который представляет собой структурированный язык и протокол взаимодействия агентов. Применение этого языка дает ряд преимуществ: расширяемость системы, способность вступать во взаимодействие с агентами других систем, независимость протокола переговоров от конкретного разработчика системы.
Первым шагом разработки сценариев переговоров внутри системы является построение диаграмм последовательности переговоров (Sequence Diagram, SD). С помощью диаграмм мы определяем минимальное количество агентов, число сообщений, их порядок и содержание. При этом, количество диаграмм определяется числом возможных ситуаций в системе. В разработанной многоагентной системе возможны следующие две основные ситуации:
•	Запрос получен от пользователя. Тогда нам необходимы следующие агенты: интерфейсный агент (InterfaceAgent) для оказания помощи пользователю и пересылки его запроса, электронного адреса и параметров вывода; агент‑менеджер (ControlAgent) для обработки запроса; агенты‑исполнители (SQLAgent, MailAgent) для поиска информации в локальной базе данных и отправки ответа пользователю. Таким образом, мы получили первую SD‑диаграмму (рис. 3).
•	Запрос отправляется с другого сервера системы. Тогда нам необходимы следующие агенты: агенты‑менеджеры (ControlAgent, отправитель и получатель); агент‑исполнитель (SQLAgent) для поиска информации в локальной базе данных. Вторая SD‑диаграмма представлена на рис. 4.

Рис. 4 SD-диаграмма №2

количество записей

количество записей

URL ответа

запрос

sql-запрос

ContolAgent1

ControlAgentN

SQLAgent

Рис. 3 SD-диаграмма №1

адрес клиента и ответа

количество записей

URL ответа

запрос

параметры вывода

адрес клиента

sql-запрос

InterfaceAgent

ControlAgent

SQLAgent

MailAgent

 Вторым шагом разработки сценариев переговоров является построение общей диаграммы Сообщений (Message Diagram, MD; рис. 5) на основе SD-диаграмм. Мы объединяем одинаковых агентов (ControlAgent) и подбираем нужные kqml-команды.
Таким образом, мы получили ряд сообщений на языке KQML:
1.	передача sql-запроса (InterfaceAgent → ControlAgent1)  
(recruit-all
	:content (<sql-запрос>)
	:language SQL
	:sender InterfaceAgent
	:receiver ControlAgent1)	 
2.	передача адреса пользователя  (InterfaceAgent → ControlAgent1)
(transport-address
	:content (<email пользователя>)
	:language Mail
	:sender InterfaceAgent
	:receiver ControlAgent1)	
3.	передача параметров вывода  (InterfaceAgent → ControlAgen1)
(tell
	:content (<параметры>)
	:language HTTP
	:ontology PARAM
	:sender InterfaceAgent
	:receiver ControlAgent1)
4.	передача запроса другим серверам  (ControlAgent1 → ControlAgentN)
 (ask-all
	:content (<sql-запрос>)
	:language SQL
	:sender ControlAgent1
	:receiver ControlAgentN

Рис. 5 Диаграмма Сообщений

reply

число записей

запрос

адрес и ответ

число записей

запрос

reply | sorry

ask-all

break

tell

transport-address

recruit-all

InterfaceAgent

ControlAgent1

ControlAgentN

SQLAgent

MailAgent

SQLAgent

MailAgent

	reply-with questionN)
5.	передача числа найденных записей, или сообщения о том, что информации нет (ControlAgentN → ControlAgent1)
(reply
	:content (<число найденных записей>)
	:language numeric
	:sender ControlAgentN
	:receiver ControlAgent1
	:in-reply-to questionN)
(sorry
	:sender ControlAgentN
	:receiver ControlAgent1
	:in-reply-to questionN)
6.	передача URL-адреса страницы с результатами (SQLAgentN → ControlAgent1) 
(reply
	:content (<адрес ответа>)
	:language HTTP
	:sender SQLAgentN
	:receiver ControlAgent1
	:in-reply-to questionN)
Поскольку SQLAgent и MailAgent являются агентами-исполнителями, то у них нет необходимости понимать язык KQML. ControlAgent распознает KQML-сообщение и вызывает нужного агента.

2.4.2 Особенности программной реализации многоагентной системы
Клиентская часть многоагентной системы реализована с применением языков РНР и Java. Предполагается, что с помощью разработанной интерфейсной формы пользователь формирует запрос к распределенной информационной системе. При этом InterfaceAgent выполняет функцию передачи данных серверу (передает ему запрос и электронный адрес клиента, а также формат вывода информации). 
При своей инициализации InterfaceAgent вычисляет доменное имя компьютера (хост), с которого он был запущен.
URL applet_source = getCodeBase();
server_name = applet_source.getHost();
В качестве номера порта, на котором работает ControlAgent, берется либо параметр, заданный при запуске агента, либо номер 1500. 
String port = getParameter("server_port");
if(port==null)  port = "1500";
Для передачи данных между сервером и InterfaceAgent используется сетевое соединение – сокет. Интерфейс сокетов позволяет передавать данные между двумя приложениями, работающими на одном или разных узлах сети. Сокет создается как объект класса Socket, с указанием хоста серверного приложения и номера порта, используемого сервером.
server_socket  = new Socket(server_name,server_port);
Далее создаются входной и выходной потоки для обмена информацией. На стороне клиента эта операция выполняется точно также как и на стороне сервера.
server_receive = new BufferedReader(new 								InputStreamReader(server_socket.getInputStream()));
server_send    = new PrintStream(server_socket.getOutputStream());
При успешном соединении InterfaceAgent передает серверу данные (электронный адрес пользователя) и команду SQL-ALL:<запрос>. Эта команда означает, что ControlAgent должен передать запрос клиента всем доступным серверам системы TORIS.
server_send.println(email);
server_send.println(command);
Если передача информации серверу происходит нормально, то агент сообщает пользователю о том, что его запрос принят системой для обработки и результат будет выслан по электронной почте. Затем он  завершает свою работу, закрывая сетевое соединение.
finally {  if(server_receive!=null) server_receive.close();
    if(server_send!=null)    server_send.   close();
    if(server_socket!=null)  server_socket. close(); } 
Серверная часть мультиагентной системы реализована на  Java. В нее входят: ControlAgent, SQLAgent и MailAgent. При этом ControlAgent управляет работой агентов и осуществляет связь с интерфейсным агентом и другими серверами системы. SQLAgent  ищет информацию в локальной базе данных, а MailAgent отправляет результат клиенту.
Агент-менеджер (ControlAgent) состоит из двух основных классов. Первый загружает данные о системе TORIS - список серверов системы, номера портов, на которых работают другие агенты-менеджеры, даты обновления файлов системы. Когда подключается клиент, этот класс создает экземпляр второго класса, который реализует интерфейс Runnable, и передает созданному экземпляру объект Socket, связанный с клиентом. В качестве клиента могут выступать либо InterfaceAgent, либо агент-менеджер, работающий на другом сервере системы TORIS.
ControlAgent control_agent = new ControlAgent(this,client_socket);
Thread agent_thread = new Thread(control_agent);
agent_thread.start();
Этот второй объект работает в отдельном потоке выполнения, что позволяет агенту-менеджеру вернуться к ожиданию других клиентов вместо того, чтобы работать только с одним.	
Установка канала связи с клиентом выполняется при помощи метода accept, определенного в классе ServerSocket. Для этого необходимо указать номер порта и максимальную длину очереди.
listen_socket = new ServerSocket(server_port,max_clients);
Socket client_socket = listen_socket.accept();Метод accept приостанавливает работу сервера до тех пор, пока клиент не установит канал связи с ним.
После обращения клиента, создаются входной и выходной потоки. 
client_send    = new PrintStream    (my_socket.getOutputStream());
client_receive = new BufferedReader(new  
InputStreamReader(my_socket.getInputStream()));
Для исключения задержек в передаче данных из-за накопления данных в буфере необходимо принудительно сбрасывать содержимое буфера методом flush. 
client_ send.flush();
Агент-менеджер получает команды от клиента и интерпретирует их, используя дополнительный класс KQMLmsq. 
Для связи с другими серверами также используются сокеты, только в этом случае агент-менеджер уже выступает в качестве клиента другого сервера. 
Для хранения получаемой информации создается результирующий файл:
do {     file_name=new String("res"+(num++)+".html");	result_file = new File(result_dir,file_name);
} while(result_file.exists());
В этом файле хранятся ссылки на php-скрипты, которые и будут в конечном итоге выводить данные, полученные на различных серверах. Каждому серверу сопоставляется одна ссылка, при условии, что запрос обработан успешно. Это сделано для того, чтобы не передавать много данных через сетевое соединение, а передавать только ссылки на найденную информацию.
Для поиска в локальной базе данных агент-менеджер активизирует SQL-агента и передает ему запрос и ссылку на выходной поток (сокет, результирующий файл).
Для связи с базой данных SQLAgent использует драйвер баз данных posgresql:
Driver driver = (Driver) lass.forName("org.postgresql.Driver").newInstance();
DriverManager.registerDriver(driver);
Connection con =DriverManager.getConnection("jdbc:postgresql:"+
control_agent.GetSiteTitle(),"user","user_passwd");
Имя базы данных совпадает с именем сервера, а для поиска данных достаточно использовать общий login и пароль, а не спрашивать их у пользователя при входе в систему.
После установки связи с базой данных агент передает запрос и получает ответ:
Statement stmt = con.createStatement();
ResultSet res = stmt.executeQuery(sql_query);
ResultSetMetaData rsmb=res.getMetaData();
Для хранения результатов поиска создается файл с расширением dat. Ссылка на php-скрипт, которая будет выводить данные, записывается во входной поток, а название файла передается как параметр для этой формы:
out_stream1.println("<FONT size=5><A HREF=http://toris.krc.karelia.ru/
TORIS/java_search/sresult.ru.phtml?filename="+file_name+param+">KareliaToris</A></font>");  
При получении ответа на запрос возникает “проблема русификации”, в связи с этим осуществляется  перекодировка полученной информации.
InputStream str1=res.getUnicodeStream(i);
byte str2[]; byte str3[]; 
int sizeCol=rsmb.getColumnDisplaySize(i); 
str2 = new byte[sizeCol+sizeCol]; str3 = new byte[sizeCol+sizeCol];
try{ int length = str1.read(str2); int k=0; int j;   
	  for (j=0; j<sizeCol*2; j++) {
       if (str2[j] != 0) { str3[k]=str2[j];out_stream.write(str3[k]); k=k+1; } } 
Когда агент-менеджер соберет всю информацию от других серверов системы, он передает ссылку на результирующий html-файл MailAgent, который и отправляет эту ссылку пользователю по электронной почте.
MailAgent для отправки сообщений использует пакет javax.mail.
Данные на сервере хранятся 10 дней, а затем они автоматически удаляются.
Работы с KQML-сообщениями нами был разработан дополнительный класс KQMLmsq на языке Java, который позволяет создавать, редактировать и разбирать KQML-сообщения.