⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tij0196.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 2 页
字号:
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ExactTimeServer</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class. The 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>RemoteTimeServer</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is the application that creates a server object, registers it with the ORB,
gives a name to the object reference, and then sits quietly waiting for client
requests.
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#0000ff">import</font> RemoteTime.*;

<font color="#0000ff">import</font> org.omg.CosNaming.*;
<font color="#0000ff">import</font> org.omg.CosNaming.NamingContextPackage.*;
<font color="#0000ff">import</font> org.omg.CORBA.*;

<font color="#0000ff">import</font> java.util.*;
<font color="#0000ff">import</font> java.text.*;

<font color="#009900">// Server object implementation</font>
<font color="#0000ff">class</font> ExactTimeServer <font color="#0000ff">extends</font> _ExactTimeImplBase{
  <font color="#0000ff">public</font> String getTime(){
    <font color="#0000ff">return</font> DateFormat.
        getTimeInstance(DateFormat.FULL).
          format(<font color="#0000ff">new</font> Date(
              System.currentTimeMillis()));
  }
}

<font color="#009900">// Remote application implementation</font>
<font color="#0000ff">public</font> <font color="#0000ff">class</font> RemoteTimeServer {
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String args[])  {
    <font color="#0000ff">try</font> {
      <font color="#009900">// ORB creation and initialization:</font>
      ORB orb = ORB.init(args, <font color="#0000ff">null</font>);
      <font color="#009900">// Create the server object and register it:</font>
      ExactTimeServer timeServerObjRef = 
        <font color="#0000ff">new</font> ExactTimeServer();
      orb.connect(timeServerObjRef);
      <font color="#009900">// Get the root naming context:</font>
      org.omg.CORBA.Object objRef = 
        orb.resolve_initial_references(
          "NameService");
      NamingContext ncRef = 
        NamingContextHelper.narrow(objRef);
      <font color="#009900">// Assign a string name to the </font>
      <font color="#009900">// object reference (binding):</font>
      NameComponent nc = 
        <font color="#0000ff">new</font> NameComponent("ExactTime", "");
      NameComponent path[] = {nc};
      ncRef.rebind(path, timeServerObjRef);
      <font color="#009900">// Wait for client requests:</font>
      java.lang.Object sync =
        <font color="#0000ff">new</font> java.lang.Object();
      <font color="#0000ff">synchronized</font>(sync){
        sync.wait();
      }
    }
    <font color="#0000ff">catch</font> (Exception e)  {
      System.out.println(
         "Remote Time server error: " + e);
      e.printStackTrace(System.out);
    }
  }
}</PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">As
you can see, implementing the server object is simple; it&#8217;s a regular
Java class that inherits from the skeleton code generated by the IDL compiler.
Things get a bit more complicated when it comes to interacting with the ORB and
other CORBA services.
</FONT><P></DIV>
<A NAME="Heading626"></A><H4 ALIGN=LEFT>
Some
CORBA services
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
is a short description of what the JavaIDL-related code is doing (primarily
ignoring the part of the CORBA code that is vendor dependent). The first line in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>main(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
starts up the ORB, and of course, this is because our server object will need
to interact with it. Right after the ORB initialization, a server object is
created. Actually, the right term would be a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>transient
servant object
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:
an object that receives requests from clients, and whose lifetime is the same
as the process that creates it. Once the transient servant object is created,
it is registered with the ORB, which means that the ORB knows of its existence
and can now forward requests to it.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Up
to this point, all we have is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>timeServerObjRef</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
an object reference that is known only inside the current server process. The
next step will be to assign a stringified name to this servant object; clients
will use that name to locate the servant object. We accomplish this operation
using the Naming Service. First, we need an object reference to the Naming
Service; the call to 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>resolve_initial_references(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
takes the stringified object reference of the Naming Service that is
&#8220;NameService,&#8221; in JavaIDL, and returns an object reference. This is
cast to a specific 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>NamingContext</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
reference using the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>narrow(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method. We can use now the naming services.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">To
bind the servant object with a stringified object reference, we first create a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>NameComponent</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object, initialized with &#8220;ExactTime,&#8221; the name string we want to
bind to the servant object. Then, using the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>rebind(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method, the stringified reference is bound to the object reference. We use 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>rebind(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to assign a reference, even if it already exists, whereas 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>bind(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
raises an exception if the reference already exists. A name is made up in CORBA
by a sequence of NameContexts &#8211; that&#8217;s why we use an array to bind
the name to the object reference.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
servant object is finally ready for use by clients. At this point, the server
process enters a wait state. Again, this is because it is a transient servant,
so its lifetime is confined to the server process. JavaIDL does not currently
support persistent objects &#8211; objects that survive the execution of the
process that creates them.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Now
that we have an idea of what the server code is doing, let&#8217;s look at the
client code:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#0000ff">import</font> RemoteTime.*;
<font color="#0000ff">import</font> org.omg.CosNaming.*;
<font color="#0000ff">import</font> org.omg.CORBA.*;

<font color="#0000ff">public</font> <font color="#0000ff">class</font> RemoteTimeClient {
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String args[]) {
    <font color="#0000ff">try</font> {
      <font color="#009900">// ORB creation and initialization:</font>
      ORB orb = ORB.init(args, <font color="#0000ff">null</font>);
      <font color="#009900">// Get the root naming context:</font>
      org.omg.CORBA.Object objRef = 
        orb.resolve_initial_references(
          "NameService");
      NamingContext ncRef = 
        NamingContextHelper.narrow(objRef);
      <font color="#009900">// Get (resolve) the stringified object </font>
      <font color="#009900">// reference for the time server:</font>
      NameComponent nc = 
        <font color="#0000ff">new</font> NameComponent("ExactTime", "");
      NameComponent path[] = {nc};
      ExactTime timeObjRef = 
        ExactTimeHelper.narrow(
          ncRef.resolve(path));
      <font color="#009900">// Make requests to the server object:</font>
      String exactTime = timeObjRef.getTime();
      System.out.println(exactTime);
    } <font color="#0000ff">catch</font> (Exception e) {
      System.out.println(
         "Remote Time server error: " + e);
      e.printStackTrace(System.out);
    }
  }
}</PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
first few lines do the same as they do in the server process: the ORB is
initialized and a reference to the naming service server is resolved. Next, we
need an object reference for the servant object, so we pass the stringified
object reference to the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>resolve(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method, and we cast the result into an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ExactTime</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
interface reference using the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>narrow(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method. Finally, we call 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getTime(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
</FONT><P></DIV>
<A NAME="Heading627"></A><H4 ALIGN=LEFT>
Activating
the name service process
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Finally
we have a server and a client application ready to interoperate. You&#8217;ve
seen that both need the naming service to bind and resolve stringified object
references. You must start the naming service process before running either the
server or the client. In JavaIDL, the naming service is a Java application that
comes with the product package, but it can be different with other products.
The JavaIDL naming service runs inside an instance of the JVM and listens by
default to network port 900.
</FONT><P></DIV>
<A NAME="Heading628"></A><H4 ALIGN=LEFT>
Activating
the server and the client
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Now
you are ready to start your server and client application (in this order, since
our server is transient). If everything is set up correctly, what you&#8217;ll
get is a single output line on the client console window, giving you the
current time. Of course, this might be not very exciting by itself, but you
should take one thing into account: even if they are on the same physical
machine, the client and the server application are running inside different
virtual machines and they can communicate via an underlying integration layer,
the ORB and the Naming Service.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
is a simple example, designed to work without a network, but an ORB is usually
configured for location transparency. When the server and the client are on
different machines, the ORB can resolve remote stringified references using a
component known as the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>Implementation
Repository
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Although the Implementation Repository is part of CORBA, there is almost no
specification, so it differs from vendor to vendor.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">As
you can see, there is much more to CORBA than what has been covered here, but
you should get the basic idea. If you want more information about CORBA, the
place to start is the OMG Web site, at http://www.omg.org
<A HREF="http://www.omg.org">http://www.omg.org</A>.
There you&#8217;ll find documentation, white papers, proceedings, and
references to other CORBA sources and products.
</FONT><a name="_Toc408018844"></a><P></DIV>
<A NAME="Heading629"></A><H3 ALIGN=LEFT>
Java
Applets and CORBA
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Java
applets can act as CORBA clients. This way, an applet can access remote
information and services exposed as CORBA objects. But an applet can connect
only with the server from which it was downloaded, so all the CORBA objects the
applet interacts with must be on that server. This is the opposite of what
CORBA tries to do: give you complete location transparency.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
is an issue of network security. If you&#8217;re on an Intranet, one solution
is to loosen the security restrictions on the browser. Or, set up a firewall
policy for connecting with external servers.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Some
Java ORB products offer proprietary solutions to this problem. For example,
some implement what is called HTTP Tunneling, while others have their special
firewall features.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
is too complex a topic to be covered in an appendix, but it is definitely
something you should be aware of.
</FONT><a name="_Toc408018845"></a><P></DIV>
<A NAME="Heading630"></A><H3 ALIGN=LEFT>
CORBA
vs. RMI
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
saw that one of the main CORBA features is RPC support, which allows your local
objects to call methods in remote objects. Of course, there already is a native
Java feature that does exactly the same thing: RMI (see Chapter 15). While RMI
makes RPC possible between Java objects, CORBA makes RPC possible between
objects implemented in any language. It&#8217;s a big difference.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">However,
<A NAME="Index3123"></A>RMI
can be used to call services on remote, non-Java code. All you need is some
kind of wrapper Java object around the non-Java code on the server side. The
wrapper object connects externally to Java clients via RMI, and internally
connects to the non-Java code using one of the techniques shown above, such as
JNI or J/Direct.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
approach requires you to write a kind of integration layer, which is exactly
what CORBA does for you, but then you don&#8217;t need a third-party ORB.
</FONT><a name="_Toc408018846"></a><P></DIV>

<div align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0195.html">Prev</a> | <a href="tij0197.html">Next</a>
</div>
</body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -