Spec-Zone .ru
спецификации, руководства, описания, API
|
Клиентские программы часто реагируют на изменения или обновления, которые происходят в сервере. Например, клиентский график или программа электронной таблицы, возможно, должны были бы быть обновлены с каждым обновлением курса акций о сервере фондового рынка. У клиента есть две опции в этом сценарии:
Пример в этом документе иллюстрирует, как клиентская программа может передать объект обратного вызова к серверу, и сервер может тогда обратный вызов, чтобы уведомить изменения клиенту. В это время мы обеспечили код для расширения простого приложения. Примечания об упрощении приложения содержатся в пределах кода.
Этот документ обеспечивает код для:
Инструкции для компиляции и выполнения примера также обеспечиваются.
Для приложения в качестве примера файл callback.idl похож на это:
interface Listener { void message(in string msg); }; interface MessageServer { void register(in Listener lt); };
Для приложения в качестве примера файл Server.java похож следующим образом.
import org.omg.CORBA.ORB; import org.omg.PortableServer.POA; import org.omg.PortableServer.POAHelper; import org.omg.CosNaming.NameComponent; import org.omg.CosNaming.NamingContext; import org.omg.CosNaming.NamingContextHelper; public class Server { public static void main(String[] args) { try { //create and initialize the ORB Properties props = System.getProperties(); props.put("org.omg.CORBA.ORBInitialPort", "1050"); //Replace MyHost with the name of the host on which you are running the server props.put("org.omg.CORBA.ORBInitialHost", "<MyHost>"); ORB orb = ORB.init(args, props); System.out.println("Initialized ORB"); //Instantiate Servant and create reference POA rootPOA = POAHelper.narrow( orb.resolve_initial_references("RootPOA")); MessageServerImpl msImpl = new MessageServerImpl(); rootPOA.activate_object(msImpl); MessageServer msRef = MessageServerHelper.narrow( rootPOA.servant_to_reference(msImpl)); //Bind reference with NameService NamingContext namingContext = NamingContextHelper.narrow( orb.resolve_initial_references("NameService")); System.out.println("Resolved NameService"); NameComponent[] nc = { new NameComponent("MessageServer", "") }; namingContext.rebind(nc, msRef); //Activate rootpoa rootPOA.the_POAManager().activate(); //Start readthread and wait for incoming requests System.out.println("Server ready and running ...."); //REMOVE THE NEXT LINE FOR THE SIMPLER EXAMPLE msImpl.startReadThread(); orb.run(); } catch (Exception e) { e.printStackTrace(); } } }
Файл регистрирует новые клиенты, принимает сообщения, тогда передает сообщения зарегистрированным клиентам. Для приложения в качестве примера файл MessageServerImpl.java похож на следующий пример.
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Vector; import java.util.Iterator; public class MessageServerImpl extends MessageServerPOA { private Vector clients = new Vector(); private ReadThread rt = null; public MessageServerImpl() { rt = new ReadThread(this); } public void register(Listener lt) { clients.add(lt); } public void startReadThread() { rt.start(); } public void message(String msg) { Iterator it = clients.iterator(); while (it.hasNext()) { Listener lt = (Listener) it.next(); lt.message(msg); //FOR THE SIMPLER EXAMPLE, ADD A SIMPLE //MESSAGE TO BE CALLED BACK, FOR EXAMPLE, //SLEEP FOR 30 SECONDS, THEN SEND THE TIME } } } //EXCLUDE THIS CLASS FOR THE SIMPLER EXAMPLE class ReadThread extends Thread { MessageServerImpl msImpl = null; public ReadThread(MessageServerImpl msImpl) { this.msImpl = msImpl; } public void run() { BufferedReader br = new BufferedReader( new InputStreamReader(System.in)); try { for (;;) { System.out.print("message > "); String msg = br.readLine(); msImpl.message(msg); } } catch (Exception e) { e.printStackTrace(); } } }
Для приложения в качестве примера файл файл Client.java похож на следующий пример.
import java.util.Properties; import org.omg.CORBA.ORB; import org.omg.PortableServer.POA; import org.omg.PortableServer.POAHelper; import org.omg.CosNaming.NameComponent; import org.omg.CosNaming.NamingContext; import org.omg.CosNaming.NamingContextHelper; public class Client { public static void main(String[] args) { try { //initialize orb Properties props = System.getProperties(); props.put("org.omg.CORBA.ORBInitialPort", "1050"); //Replace MyHost with the name of the host on which you are running the server props.put("org.omg.CORBA.ORBInitialHost", "<MyHost>"); ORB orb = ORB.init(args, props); System.out.println("Initialized ORB"); //Instantiate Servant and create reference POA rootPOA = POAHelper.narrow( orb.resolve_initial_references("RootPOA")); ListenerImpl listener = new ListenerImpl(); rootPOA.activate_object(listener); Listener ref = ListenerHelper.narrow( rootPOA.servant_to_reference(listener)); //Resolve MessageServer MessageServer msgServer = MessageServerHelper.narrow( orb.string_to_object("corbaname:iiop:1.2@localhost:1050#MessageServer")); //Register listener reference (callback object) with MessageServer msgServer.register(ref); System.out.println("Listener registered with MessageServer"); //Activate rootpoa rootPOA.the_POAManager().activate(); //Wait for messages System.out.println("Wait for incoming messages"); orb.run(); } catch (Exception e) { e.printStackTrace(); } } }
Когда Слушатель идентифицирует это, сообщение было получено от сервера, оно выводит на экран сообщение на клиенте. Для приложения в качестве примера файл ListenerImpl.java похож на следующий пример.
public class ListenerImpl extends ListenerPOA { public void message(String msg) { System.out.println("Message from server : " + msg); } }
rm -rf ./classes ./orb.db
mkdir -p ./classes <path_to_java>/bin/idlj -fall -td ./classes callback.idl
<path_to_java>/bin/javac -classpath ./classes -d ./classes *.java
<path_to_java>/bin/orbd -ORBInitialPort 1050 -ORBInitialHost <host_name> &
<path_to_java>/bin/java -classpath ./classes Server -ORBInitialPort 1050
После того, как Вы запустили сервер, Вы будете видеть, выводит, такие как следующее в окне терминала:
Initialized ORB Resolved NameService Server ready and running .... message >
При этой подсказке Вы отправите сообщения клиенту, но сначала Вы должны запустить клиентское приложение. От КЛИЕНТСКОГО терминала следуйте за этими шагами, чтобы выполнить клиент. Удостоверьтесь, что Вы использовали имя хоста, на котором сервер работает в разделе свойств клиентского кода.
<path_to_java>/bin/java -classpath ./classes Client -ORBInitialPort 1050
Вывод от клиента выведет на экран в формате, подобном этому:
Initialized ORB Listener registered with MessageServer Wait for incoming messages
Чтобы вывести на экран функциональность использования обратного вызова, Вы ввели бы данные в терминал сервера при подсказке, и это выведет на экран на всех клиентских терминалах. Это могло быть чем-либо, где клиенты интересуются некоторыми уведомлениями.
Одним примером является футбольный игровой счет, где клиенты уведомляются всякий раз, когда счет изменяется.
message > Niners TD. Niners 7 - Giants 0 message > Giants TD. Niners 7 - Giants 7 message > Niners TD. Niners 14 - Giants 7
Когда сообщения, такие как показанные выше отправляются, клиентский дисплей выглядит подобным следующему:
Wait for incoming messages Message from server : Niners TD. Niners 7 - Giants 0 Message from server : Giants TD. Niners 7 - Giants 7 Message from server : Niners TD. Niners 14 - Giants 7