// client.cpp,v 1.5 2000/01/19 02:40:01 irfan Exp // ================================================================ // // = FILENAME // client.cpp // // = DESCRIPTION // This is a client that uses AMI calls. // // = AUTHOR // Irfan Pyarali // // ================================================================ #include "ace/Get_Opt.h" #include "ace/Read_Buffer.h" #include "testS.h" ACE_RCSID(AMI, client, "client.cpp,v 1.5 2000/01/19 02:40:01 irfan Exp") // Name of file contains ior. static const char *IOR = "file://ior"; // Default iterations. static CORBA::ULong iterations = 20; // Time interval between invocation (in milli seconds). static long interval = 1000; // Flag indicates whether to shutdown remote server or not upon client // shutdown. static int shutdown_server = 0; // AMI call or regular call. static int invoke_ami_style = 1; // Flag indicates that all replies have been received static int received_all_replies = 0; class Reply_Handler : public POA_AMI_testHandler { public: void method (CORBA::ULong reply_number, CORBA::Environment &) ACE_THROW_SPEC ((CORBA::SystemException)) { ACE_DEBUG ((LM_DEBUG, "client: AMI Reply %d @ %T\n", reply_number)); // Last reply flips the flag. if (reply_number == iterations) received_all_replies = 1; } void method_excep (AMI_testExceptionHolder *, CORBA::Environment &ACE_TRY_ENV) ACE_THROW_SPEC ((CORBA::SystemException)) { ACE_PRINT_EXCEPTION ((*ACE_TRY_ENV.exception ()), "AMI exception caught:"); } #ifdef ADDITIONAL // NOTE: the additional_method has to be implemented if it was // given in the IDL file! void additional_method (CORBA::ULong reply_number, CORBA::Environment &) ACE_THROW_SPEC ((CORBA::SystemException)) { ACE_DEBUG ((LM_DEBUG, "client: AMI Reply %d @ %T\n", reply_number)); // Last reply flips the flag. if (reply_number == iterations) received_all_replies = 1; } void additional_method_excep (AMI_testExceptionHolder *, CORBA::Environment &ACE_TRY_ENV) ACE_THROW_SPEC ((CORBA::SystemException)) { ACE_PRINT_EXCEPTION ((*ACE_TRY_ENV.exception ()), "AMI exception caught:"); } #endif ADDITIONAL }; static int parse_args (int argc, char **argv) { ACE_Get_Opt get_opts (argc, argv, "a:b:k:m:i:t:x"); int c; while ((c = get_opts ()) != -1) switch (c) { case 'k': IOR = get_opts.optarg; break; case 'a': invoke_ami_style = ::atoi (get_opts.optarg); break; case 'i': iterations = ::atoi (get_opts.optarg); break; case 't': interval = ::atoi (get_opts.optarg); break; case 'x': shutdown_server = 1; break; case '?': default: ACE_ERROR_RETURN ((LM_ERROR, "usage: %s " "-k IOR " "-a invoke AMI style [0/1] " "-i iterations " "-t interval between calls " "-x shutdown server " "\n", argv [0]), -1); } if (IOR == 0) ACE_ERROR_RETURN ((LM_ERROR, "Please specify the IOR for the servant\n"), -1); // Without AMI, replies are immediate. if (!invoke_ami_style) received_all_replies = 1; // Indicates successful parsing of command line. return 0; } int main (int argc, char **argv) { ACE_DECLARE_NEW_CORBA_ENV; ACE_TRY { // Initialize the ORB. CORBA::ORB_var orb = CORBA::ORB_init (argc, argv, 0, ACE_TRY_ENV); ACE_TRY_CHECK; // Initialize options based on command-line arguments. int parse_args_result = parse_args (argc, argv); if (parse_args_result != 0) return parse_args_result; CORBA::Object_var base = orb->resolve_initial_references ("RootPOA", ACE_TRY_ENV); ACE_TRY_CHECK; PortableServer::POA_var root_poa = PortableServer::POA::_narrow (base.in (), ACE_TRY_ENV); ACE_TRY_CHECK; // Get an object reference from the argument string. base = orb->string_to_object (IOR, ACE_TRY_ENV); ACE_TRY_CHECK; PortableServer::POAManager_var poa_manager = root_poa->the_POAManager (ACE_TRY_ENV); ACE_TRY_CHECK; poa_manager->activate (ACE_TRY_ENV); ACE_TRY_CHECK; // Try to narrow the object reference to a reference. test_var test_object = test::_narrow (base.in (), ACE_TRY_ENV); ACE_TRY_CHECK; Reply_Handler reply_handler_servant; AMI_testHandler_var reply_handler_object = reply_handler_servant._this (ACE_TRY_ENV); ACE_TRY_CHECK; for (CORBA::ULong i = 1; i <= iterations; ++i) { ACE_DEBUG ((LM_DEBUG, "client: Iteration %d @ %T\n", i)); if (invoke_ami_style) { // Invoke the AMI method. test_object->sendc_method (reply_handler_object.in (), i, ACE_TRY_ENV); ACE_TRY_CHECK; } else { CORBA::ULong reply_number = 0; // Invoke the regular method. test_object->method (i, reply_number, ACE_TRY_ENV); ACE_TRY_CHECK; ACE_DEBUG ((LM_DEBUG, "client: Regular Reply %d @ %T\n", reply_number)); } // Interval between successive calls. ACE_Time_Value sleep_interval (0, interval * 1000); orb->run (sleep_interval); } // Loop until all replies have been received. while (!received_all_replies) { orb->perform_work (); } // Shutdown server. if (shutdown_server) { test_object->shutdown (ACE_TRY_ENV); ACE_TRY_CHECK; } root_poa->destroy (1, 1, ACE_TRY_ENV); ACE_TRY_CHECK; // Destroy the ORB. On some platforms, e.g., Win32, the socket // library is closed at the end of main(). This means that any // socket calls made after main() fail. Hence if we wait for // static destructors to flush the queues, it will be too late. // Therefore, we use explicit destruction here and flush the // queues before main() ends. orb->destroy (ACE_TRY_ENV); ACE_TRY_CHECK; } ACE_CATCHANY { ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Exception caught:"); return -1; } ACE_ENDTRY; ACE_CHECK_RETURN (-1); return 0; }