Xây dựng Úng dụng Corba khách/chủ trong môi trường java
Chúng ta sẽ xem xét một ví dụ sử dụng Corba Đầu tiên chúng ta sẽ định nghĩa IDL cho đối tượng từ xa. interface Icalculator { double TinhToan(in double so1, in double so2, in char pt); }; Bây giờ chúng ...
Chúng ta sẽ xem xét một ví dụ sử dụng Corba
Đầu tiên chúng ta sẽ định nghĩa IDL cho đối tượng từ xa.
interface Icalculator {
double TinhToan(in double so1, in double so2, in char pt);
};
Bây giờ chúng ta có thể biên dịch IDL dùng lệnh idlj. Tham số -fall phát sinh mã cả 2 phía máy khách và máy chủ:
idlj -fall Icalculator.idl
Sau khi biên dịch IDL, sẽ phát sinh một số tập tin sau:
IcalculatorStub. Java: là mã stub.
Icalculator.Java: là giao diện từ xa..
IcalculatorHolder.Java là mã hỗ trợ.
IcalculatorHelper.Java là mã hỗ trợ.
IcalculatorOperations.Java là mã hỗ trợ.
IcalculatorPOA.Java là mã skeleton và là lớp cha chúng ta thừa kế khi cài đặt mã bên phía máy chủ.
Tiếp đến chúng ta sẽ cài đặt lớp bên phía máy chủ được gọi là clsRemote và thừa kế từ lớp gốc phát sinh khi dịch IDL:
class clsRemote extends _lctIRemoteObImplBase{
public clsRemoteO() {
}
public double TinhToan (double so1, double so2, char pt){
switch(pt){
case '+':
return so1 + so2;
case '-':
return so1 - so2;
case '*':
return so1 * so2;
case '/':
return so1 / so2;
case '%':
return so1 % so2;
}
return 0;
}
}
Tiếp đến chúng ta cài đặt mã bên phía máy chủ, để thực hiện việc khởi tạo đối tượng và đăng ký máy chủ tên:
import org.omg.Corba.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextExtPackage.*;
public class clsRegReO {
public static void main(String[] args) throws Exception{
System.out.println("Setup lctRemoteO");
ORB orb = ORB.init(args,null);
clsRemoteO rm = new clsRemoteO();
orb.connect(rm);//Ket noi O Corba voi moi truong ORB
//Lay dang ky den dich vu tnameserv
org.omg.Corba.Object thamChieSV = orb.resolve_initial_references("NameService");
//Chuyen kieu tham chieu den tnameserv|ve NamingContext
NamingContext nct = NamingContextExtHelper.narrow(thamChieSV);
//Tao ten cua doi tuong
NameComponent nc = new NameComponent("lctRO","");
//Tao duong dan de luu ten doi tuong
NameComponent path[] = {nc};
//Rang buoc doi tuong do vao tnameservices
nct.rebind(path,rm);
System.out.println("Server waiting....");
System.in.read();
}
}
Qua đây ta thấy Corba hơn hẳn RMI ở chỗ đối tượng RMI chỉ gọi được bởi các trình khách viết bằng Java còn các đối tượng trong Corba có thể gọi được bởi trình khách viết bằng các ngôn ngữ khác như C++, delphi…
Cuối cùng chúng ta tạo ra một chương trình bên phía máy khách để thực hiện lời gọi phương thức từ xa:
import org.omg.Corba.*;
import org.omg.CosNaming.*;
class clsRunClient {
public clsRunClient() {
}
public static void main(String[] args) throws Exception {
ORB orb = ORB.init(args, null);
//Tham chieu den dich vu tnameservices
org.omg.Corba.Object tnsv = orb.resolve_initial_references("NameService");
NamingContext nct = NamingContextExtHelper.narrow(tnsv);
NameComponent nc = new NameComponent("lctRO", "");
NameComponent path[] = {
nc};
lctIRemoteOb conS = lctIRemoteObHelper.narrow(nct.resolve(path));
double a = 13, b = 3;
System.out.println("Tổng hai số là: " + conS.TinhToan(a, b, '+'));
System.out.println("Hieu hai số là: " + conS.TinhToan(a, b, '-'));
System.out.println("Tich hai số là: " + conS.TinhToan(a, b, '*'));
System.out.println("Thuong hai số là: " + conS.TinhToan(a, b, '/'));
System.out.println("Mod hai số là: " + conS.TinhToan(a, b, '%'));
}
}
Để thực thi đoạn mã ví dụ, chúng ta phải khởi động RMI Registry, chạy đoạn mã bên phía máy chủ một lần, sau đó chúng ta có thể chạy chương trình khách:
idlj -fall -oldImplBase lctPhepToan.idl
Javac *.Java
start tnameserv
Java clsRegReO
pause
Kết quả in ra màn hình:
Tổng hai số là: 16
Hiệu hai số là: 10
Tích hai số là: 39
Thương hai số là: 4,333333
Mov hai số là: 1
Trong ví dụ trên ta khởi động trình môi giới ở hai phía khách chủ bằng lệnh:
ORB orb = ORB.init( args, null );
Phương thức tĩnh init của ORB cần hai đối số:
- Đối số thứ nhất dùng để nhận các tuỳ chọn (Nếu có).
- Đối số thứ hai do người lập trình chỉ định.
Nếu cả hai đối số này cùng mang giá trị Null ORB sẽ dùng các thông số của hệ thống mặc định.
Trong trường hợp bạn không dùng các thông số mặc định của ORB bạn cần khởi tạo các đối số cho phương thức.ORB.init();
Dưới đây là nội dung tập tin khi bạn dùng lệnh :
idlj - fall - oldImplBase Example .idl
Ví dụ 4.7.1: _IcalculatorImplBase.Java
public abstract class _IcalculatorImplBase extends org.omg.Corba.portable.ObjectImpl
implements Icalculator, org.omg.Corba.portable.InvokeHandler
{
// Constructors
public _IcalculatorImplBase ()
{
}
private static java.util.Hashtable _methods = new java.util.Hashtable ();
static
{
_methods.put ("TinhToan", new java.lang.Integer (0));
}
public org.omg.Corba.portable.OutputStream _invoke (String $method,
org.omg.Corba.portable.InputStream in,
org.omg.Corba.portable.ResponseHandler $rh)
{
org.omg.Corba.portable.OutputStream out = null;
java.lang.Integer __method = (java.lang.Integer)_methods.get ($method);
if (__method == null)
throw new org.omg.Corba.BAD_OPERATION (0, org.omg.Corba.CompletionStatus.COMPLETED_MAYBE);
switch (__method.intValue ())
{
case 0: // Icalculator/TinhToan
{
double so1 = in.read_double ();
double so2 = in.read_double ();
char pt = in.read_char ();
double $result = (double)0;
$result = this.TinhToan (so1, so2, pt);
out = $rh.createReply();
out.write_double ($result);
break;
}
default:
throw new org.omg.Corba.BAD_OPERATION (0, org.omg.Corba.CompletionStatus.COMPLETED_MAYBE);
}
return out;
} // _invoke
// Type-specific Corba::Object operations
private static String[] __ids = {
"IDL:Icalculator:1.0"};
public String[] _ids ()
{
return (String[])__ids.clone ();
}
} // class _IcalculatorImplBase
Ví dụ 4.7.2: IcalculatorStub.Java
public class _IcalculatorStub extends org.omg.Corba.portable.ObjectImpl implements Icalculator
{
public double TinhToan (double so1, double so2, char pt)
{
org.omg.Corba.portable.InputStream $in = null;
try {
org.omg.Corba.portable.OutputStream $out = _request ("TinhToan", true);
$out.write_double (so1);
$out.write_double (so2);
$out.write_char (pt);
$in = _invoke ($out);
double $result = $in.read_double ();
return $result;
} catch (org.omg.Corba.portable.ApplicationException $ex) {
$in = $ex.getInputStream ();
String _id = $ex.getId ();
throw new org.omg.Corba.MARSHAL (_id);
} catch (org.omg.Corba.portable.RemarshalException $rm) {
return TinhToan (so1, so2, pt );
} finally {
_releaseReply ($in);
}
} // TinhToan
// Type-specific Corba::Object operations
private static String[] __ids = {
"IDL:Icalculator:1.0"};
public String[] _ids ()
{
return (String[])__ids.clone ();
}
private void readObject (java.io.ObjectInputStream s) throws java.io.IOException
{
String str = s.readUTF ();
String[] args = null;
java.util.Properties props = null;
org.omg.Corba.Object obj = org.omg.Corba.ORB.init (args, props).string_to_object (str);
org.omg.Corba.portable.Delegate delegate = ((org.omg.Corba.portable.ObjectImpl) obj)._get_delegate ();
_set_delegate (delegate);
}
private void writeObject (java.io.ObjectOutputStream s) throws java.io.IOException
{
String[] args = null;
java.util.Properties props = null;
String str = org.omg.Corba.ORB.init (args, props).object_to_string (this);
s.writeUTF (str);
}
} // class _IcalculatorStub
Ví dụ 4.7.3: Icalculator
public interface Icalculator extends IcalculatorOperations, org.omg.Corba.Object, org.omg.Corba.portable.IDLEntity
{
} // interface Icalculator
Ví dụ 4.7.4:IcalculatorHelper
abstract public class IcalculatorHelper
{
private static String _id = "IDL:Icalculator:1.0";
public static void insert (org.omg.Corba.Any a, Icalculator that)
{
org.omg.Corba.portable.OutputStream out = a.create_output_stream ();
a.type (type ());
write (out, that);
a.read_value (out.create_input_stream (), type ());
}
public static Icalculator extract (org.omg.Corba.Any a)
{
return read (a.create_input_stream ());
}
private static org.omg.Corba.TypeCode __typeCode = null;
synchronized public static org.omg.Corba.TypeCode type ()
{
if (__typeCode == null)
{
__typeCode = org.omg.Corba.ORB.init ().create_interface_tc (IcalculatorHelper.id (), "Icalculator");
}
return __typeCode;
}
public static String id ()
{
return _id;
}
public static Icalculator read (org.omg.Corba.portable.InputStream istream)
{
return narrow (istream.read_Object (_IcalculatorStub.class));
}
public static void write (org.omg.Corba.portable.OutputStream ostream, Icalculator value)
{
ostream.write_Object ((org.omg.Corba.Object) value);
}
public static Icalculator narrow (org.omg.Corba.Object obj)
{
if (obj == null)
return null;
else if (obj instanceof Icalculator)
return (Icalculator)obj;
else if (!obj._is_a (id ()))
throw new org.omg.Corba.BAD_PARAM ();
else
{
org.omg.Corba.portable.Delegate delegate = ((org.omg.Corba.portable.ObjectImpl)obj)._get_delegate ();
_IcalculatorStub stub = new _IcalculatorStub ();
stub._set_delegate(delegate);
return stub;
}
}
}
Ví dụ 4.7.5: IcalculatorHolder.Java
public final class IcalculatorHolder implements org.omg.Corba.portable.Streamable
{
public Icalculator value = null;
public IcalculatorHolder ()
{
}
public IcalculatorHolder (Icalculator initialValue)
{
value = initialValue;
}
public void _read (org.omg.Corba.portable.InputStream i)
{
value = IcalculatorHelper.read (i);
}
public void _write (org.omg.Corba.portable.OutputStream o)
{
IcalculatorHelper.write (o, value);
}
public org.omg.Corba.TypeCode _type ()
{
return IcalculatorHelper.type ();
}
}
Ví dụ 4.7.6: IcalculatorOperations.Java
public interface IcalculatorOperations{
double TinhToan (double so1, double so2, char pt);
} // interface IcalculatorOperations
Dưới đây là nội dung tập tin khi bạn dùng lệnh :
idlj - fall - oldImplBase Example.idl
Ví dụ 4.8.1: IcalculatorOperations .Java
public interface IcalculatorOperations{
double TinhToan (double so1, double so2, char pt);
} // interface IcalculatorOperations
Ví dụ 4.8.2: IcalculatorHolder.Java
public final class IcalculatorHolder implements org.omg.Corba.portable.Streamable
{
public Icalculator value = null;
public IcalculatorHolder ()
{
}
public IcalculatorHolder (Icalculator initialValue)
{
value = initialValue;
}
public void _read (org.omg.Corba.portable.InputStream i)
{
value = IcalculatorHelper.read (i);
}
public void _write (org.omg.Corba.portable.OutputStream o)
{
IcalculatorHelper.write (o, value);
}
public org.omg.Corba.TypeCode _type ()
{
return IcalculatorHelper.type ();
}
}
Ví dụ 4.8.3: IcalculatorHelper.Java
abstract public class IcalculatorHelper
{
private static String _id = "IDL:Icalculator:1.0";
public static void insert (org.omg.Corba.Any a, Icalculator that)
{
org.omg.Corba.portable.OutputStream out = a.create_output_stream ();
a.type (type ());
write (out, that);
a.read_value (out.create_input_stream (), type ());
}
public static Icalculator extract (org.omg.Corba.Any a)
{
return read (a.create_input_stream ());
}
private static org.omg.Corba.TypeCode __typeCode = null;
synchronized public static org.omg.Corba.TypeCode type ()
{
if (__typeCode == null)
{
__typeCode = org.omg.Corba.ORB.init ().create_interface_tc (IcalculatorHelper.id (), "Icalculator");
}
return __typeCode;
}
public static String id ()
{
return _id;
}
public static Icalculator read (org.omg.Corba.portable.InputStream istream)
{
return narrow (istream.read_Object (_IcalculatorStub.class));
}
public static void write (org.omg.Corba.portable.OutputStream ostream, Icalculator value)
{
ostream.write_Object ((org.omg.Corba.Object) value);
}
public static Icalculator narrow (org.omg.Corba.Object obj)
{
if (obj == null)
return null;
else if (obj instanceof Icalculator)
return (Icalculator)obj;
else if (!obj._is_a (id ()))
throw new org.omg.Corba.BAD_PARAM ();
else
{
org.omg.Corba.portable.Delegate delegate = ((org.omg.Corba.portable.ObjectImpl)obj)._get_delegate ();
_IcalculatorStub stub = new _IcalculatorStub ();
stub._set_delegate(delegate);
return stub;
}
}
}
Ví dụ 4.8.4: Icalculator.Java
public interface Icalculator extends IcalculatorOperations, org.omg.Corba.Object, org.omg.Corba.portable.IDLEntity
{
} // interface Icalculator
Ví dụ 4.8.5:_IcalculatorStub .Java
public class _IcalculatorStub extends org.omg.Corba.portable.ObjectImpl implements Icalculator
{
public double TinhToan (double so1, double so2, char pt)
{
org.omg.Corba.portable.InputStream $in = null;
try {
org.omg.Corba.portable.OutputStream $out = _request ("TinhToan", true);
$out.write_double (so1);
$out.write_double (so2);
$out.write_char (pt);
$in = _invoke ($out);
double $result = $in.read_double ();
return $result;
} catch (org.omg.Corba.portable.ApplicationException $ex) {
$in = $ex.getInputStream ();
String _id = $ex.getId ();
throw new org.omg.Corba.MARSHAL (_id);
} catch (org.omg.Corba.portable.RemarshalException $rm) {
return TinhToan (so1, so2, pt );
} finally {
_releaseReply ($in);
}
} // TinhToan
// Type-specific Corba::Object operations
private static String[] __ids = {
"IDL:Icalculator:1.0"};
public String[] _ids ()
{
return (String[])__ids.clone ();
}
private void readObject (java.io.ObjectInputStream s) throws java.io.IOException
{
String str = s.readUTF ();
String[] args = null;
java.util.Properties props = null;
org.omg.Corba.Object obj = org.omg.Corba.ORB.init (args, props).string_to_object (str);
org.omg.Corba.portable.Delegate delegate = ((org.omg.Corba.portable.ObjectImpl) obj)._get_delegate ();
_set_delegate (delegate);
}
private void writeObject (java.io.ObjectOutputStream s) throws java.io.IOException
{
String[] args = null;
java.util.Properties props = null;
String str = org.omg.Corba.ORB.init (args, props).object_to_string (this);
s.writeUTF (str);
}
} // class _IcalculatorStub