Опубликован: 18.03.2010 | Доступ: свободный | Студентов: 840 / 85 | Оценка: 4.48 / 4.33 | Длительность: 12:01:00
Лекция 2:

Технология CORBA

Примеры

Пример "Служба мгновенных сообщений"

Функциональность

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

Окно регистрации и аутентификации

Рис. 2.6. Окно регистрации и аутентификации

В окне регистрации/аутентификации (Рис. 2.6) пользователь вводит свое имя и пароль, а потом нажимает одну из кнопок Регистрация (Register) или Аутентификация (Login).При регистрации сервер запоминает имя и пароль пользователя (если такое имя еще не зарегистрировано) и выполняет вход в систему с этими параметрами. При аутентификации сервер проверяет наличие комбинации имя/пароль среди ранее зарегистрированных пользователей и в случае совпадения выполняет вход в систему.

Окно сообщений

Рис. 2.7. Окно сообщений

У Ника открыто окно обмена сообщениями с Лео (Рис. 2.7). Сообщения Лео появляются на экране сразу после отправки. Кэйт зарегистрирована на сервере, но не подключена к системе в данный момент. Питер написал Нику сообщение, о чем свидетельствует синий цвет кнопки. Ник прочитает это сообщение после того, как переключится в режим общения с Питером, нажав на кнопку с его именем.

Инструменты

Разработка будет вестись на языках Java и C++ с помощью средств Java 2 SE 1.4.2 и Microsoft Visual Studio 8 (2005). В качестве брокера объектных запросов (ORB) для обоих языков будем использовать Borland VisiBroker 7.На настройке брокера остановимся подробнее.

На момент написания этого текста седьмая версия VisiBroker - единственная официально бесплатно распространяемая для ознакомительного использования ( trial, 60 дней). Стабильную версию Inprise обещает выпустить в следующем году. Описываемые здесь способы настройки могут не потребоваться при использовании окончательной версии. Временную (на 60 дней) лицензию можно получить на официальном сайте. После окончания ее действия штатная замена лицензии не помогает, требуется удалить старую лицензию как файл, и после этого установить новую.

В качестве C+ + компилятора VisiBroker 7,в отличие от предыдущих версий, поддерживает только компилятор из Visual Studio 8 (компилятор от Borland не поддерживается). Java поставляется в комплекте, причем две версии - 1.4.2 и 1.5. Несоответствие версий стало одной из причин неспособности данного брокера работать с Java без модификации. Для компиляции и выполнения написанных на Java CORBA-объектов используются входящие в VisiBroker программы vbj и vbjc вместо java и javac соответственно. При этом для компиляции используется версия JDK 1.5,а для выполнения - 1.4.2, что приводит к неработоспособности. Можно было бы добавить опцию компиляции с целью 1.4.2, но проще выбрать одну версию, в нашем случае 1.4.2. Для этого требуется заменить в файле <VBDir>\bin\toolsj dk.config строку

"javahome $var(installRoot)/jdk/jdk1.5.0"на

"javahome $var(installRoot)/jdk/jdk1.4.2".

Кроме vbj, vbjc из программ от VisiBroker нам потребуются SmartAgent и Naming Service.Первый должен быть запущен для выполнения всех примеров (кроме первого). Второй проще запускать указанным в соответствующих примерах образом. Несмотря на то, что согласно документации запуск Naming Service с соответствующими параметрами является альтернативой использованию SmartAgent,для работы текущей версии сервиса имен требуется и запуск SmartAgent,и явное указание параметров.

Интерфейс

Реализацию службы мгновенных сообщений с использованием CORBA мы начнем с описания интерфейсов CORBA -объектов на языке IDL. Создадим IDL -файл с описанием модуля Message, в котором содержатся два интерфейса - MessageReceiver и MessagingService. Методы этих интерфейсов будут доступны для вызова клиентам CORBA -объектов. Первый интерфейс реализуется на стороне клиента службы мгновенных сообщений, а второй - на стороне сервера.

module Message  
{
interface MessageReceiver  
{
void newMessage(in unsigned long from,   in string text); 
void userStatusNotification(in unsigned long uid,   in string name,   in boolean online);
};
interface MessagingService  
{
unsigned long registerUser(string userName,   in string password); 
unsigned long login(in string userName, in string password, in MessageReceiver receiver); 
boolean sendMessage(in unsigned long from, in string password, in unsigned long to, in string msg);
boolean logout(in unsigned long uid, in string password);
};

Интерфейс MessageReceiver предназначен для уведомления клиента о событиях в системе. Метод newMessage уведомляет клиента о новом предназначенном ему сообщении, а метод userStatusNotification - об изменении статуса других пользователей службы.

Интерфейс сервера MessagingService предоставляет методы для регистрации пользователя ( registerUser ), аутентификации ( login ), отправки сообщения конкретному пользователю ( sendMessage ) и выхода из системы ( logout ). В целях гарантии аутентичности каждый метод сервера требует передачи пароля в качестве одного из параметров.

Далее IDL -файл необходимо скомпилировать, чтобы получить классы заглушек, скелетонов и другие вспомогательные классы на целевом языке программирования. Для компиляции IDL -описания в Java будем использовать команду:

idl2java [params] Message.idl

Здесь в параметрах указывается тип используемого объектного адаптера. От него зависит, какие вспомогательные классы будут созданы. Тип объектного адаптера по умолчанию - POA.Для компиляции в C+ + используется команда:

idl2cpp [params] Message.idl

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

Прямое задание IOR

В нашем первом примере и сервер и клиент службы мгновенных сообщений будут реализованы на языке Java.Для вызова методов CORBA -объекта необходимо сначала получить ссылку на этот объект. В данном примере ссылка на сервер задается явно в виде Interoperable Object Reference (IOR).

Начнем с реализации сервера службы мгновенных сообщений. Он выполняет следующие действия:

  1. Инициализация ORB.

    ORB orb = ORB.init(args,null);

  2. Создание серванта (объекта реализации).

    Message.MessagingService messagingService = new MessagingServiceImpl();

  3. Получение IOR серванта и сохранение его в файл.

    String ior = orb.object_to_string(messagingService);

    ...

    FileWriter fw = new FileWriter("MS.ior"); fw.write(ior);

  4. Ожидание подключения клиентов.

Ниже приведен полный листинг кода сервера.

import org.omg.CORBA.*; 
import java.io.*;
public class Server  
{
public static void main(String[]   args)   
{ 
ORB orb = ORB.init(args,null); 
Message.MessagingService messagingService =new MessagingServiceImpl(); 
String ior = orb.object to string(messagingService); 
System.out.println(messagingService + " is ready.\n" + ior);
try 	
	{
	FileWriter fw = new FileWriter("MS.ior");
	fw.write(ior);
	fw.close();
	System.out.println("IOR written to file"); 
	}   
catch(IOException e)   
	{ 
	System.out.println("Failed to write IOR to file. Exception: "); 
	e.printStackTrace();
	}
try 	
	{
	Thread.currentThread().join();
	}  
catch(InterruptedException ex)   
	{}
}

Далее опишем сервант, реализующий интерфейс MessagingService. Как видно из листинга, приведенного ниже, его необходимо унаследовать от класса-скелетона Message.MessagingServiceImplBase, сгенерированного автоматически компилятором IDL.

import org.omg.CORBA.*;
import org.omg.Messaging.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.HashMap;

public class MessagingServiceImpl extends Message.MessagingServiceImplBase  
{ 
private HashMap nameToId; 
private ArrayList users; 
public MessagingServiceImpl()   
	{
	System.out.println("Constructing MessagingServiceImpl");
	nameToId = new HashMap();
	users = new ArrayList();
	}
public int registerUser (String userName, String password)   
	{ 
	if (nameToId.containsKey(userName))   
	{
	System.out.println("User " + userName + " already registered"); 
	return 0; 
	}  
	else  
	{
	int uid = nameToId.size();
	nameToId.put(userName,  new Integer(uid)); 
	users.add(new User(userName,  password)); 
	notifyAllUsers(++uid,   false); 
	System.out.println("User " + userName + " registered successfully,  user ID is  " + (new Integer(uid)).toString());
	return uid;
	}
	}
...
private void notifyAllUsers(int uid,  boolean online)
	{
	String userName = ((User)users.get(uid - 1)).name;
	for (int i = 0;  i < users.size(); ++i)	
		{
		if (i   != uid - 1)   
			{
			User buddy = (User)users.get(i);
			if (buddy.online)   
				{
				buddy.receiver.userStatusNotification( uid,  userName,   online);
				}
			}
		}
	}
class User {... } 
class Msg    {... }
}

Теперь создадим клиент службы мгновенных сообщений. Он выполняет следующие действия:

  1. Инициализация ORB.

    ORB orb = ORB.init(args, null);

  2. Получение IOR сервера из файла.

    String ior = br.readLine();

  3. Преобразование IOR сервера в CORBA -объект и приведение его к соответствующему типу.

    org.omg.CORBA.Object obj = orb.string_to_object(ior);

    Message.MessagingService service =

    Message.MessagingServiceHelper.narrow(obj);

  4. Создание окон пользовательского интерфейса и серванта.

Полный листинг класса клиента приведен ниже. Листинги классов пользовательского интерфейса можно найти в файлах с примерами.

import org.omg.CORBA.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Vector;
import java.io.*;

public class Client  
{
public static void main(String[]   args)   
{
try 
	{
	ORB orb = ORB.init(args, null); 
	FileReader fr = new FileReader("MS.ior"); 
	BufferedReader br = new BufferedReader(fr); 
	String ior = br.readLine();
	org.omg.CORBA.Object obj = orb.string_to_object(ior); 
	System.out.println(ior);
	Message.MessagingService service = Message.MessagingServiceHelper.narrow(obj);
	MessagingFrame mf = new MessagingFrame(service);
	Message.MessageReceiver receiver = new MessageReceiverImpl(mf);
	LoginFrame loginFrame = new LoginFrame(service,   receiver,  mf);
	loginFrame.show(); 
	}   
catch   (Throwable t)   
	{	t.printStackTrace();
	}
}

Наконец, создадим сервант, реализующий интерфейс MessageReceiver. По аналогии с сервантом сервера, он наследуется от скелетона Message._MessageReceiverImplBase.

import javax.swing.*; 
import org.omg.CORBA.*; 
import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import java.util.ArrayList; 
import java.util.Vector;

public class MessageReceiverImpl extends Message.MessageReceiverImplBase 
{ 
public MessageReceiverImpl(MessagingFrame mf)   
	{ 
	mesFrm = mf;
	}

public void newMessage(int from,   String text)   
	{
 	mesFrm.newMessage(from,   text); 
	System.out.println("New message from " + 
	(new Integer(from)).toString()   + ":   " + text);
	}
public void userStatusNotification(int uid,   String name,  boolean online)   
	{ 
	mesFrm.buddyStateChanged(uid,  name,   online); 
	System.out.println(name + " is now " + (online ? "online" : "offline"));
	}
private MessagingFrame mesFrm;
}
Антон Зубеков
Антон Зубеков

Здравствуйте, подскажите пожалуйста где можно достать материалы по курсу Кросс-платформенные и многозвенные технологии, о которых говориться, к примеру, в Лекции 2. Пример "Служба мгновенных сообщений"