sample/filter/server.cpp

00001 /*
00002   Сервер.
00003 
00004   Получает запросы от клиента #1 и передает их клиенту #2.
00005   Получает ответы от клиента #2 и передает их клиенту #1.
00006 */
00007 
00008 #include <iostream>
00009 #include <memory>
00010 
00011 #include <so_4/rt/h/rt.hpp>
00012 #include <so_4/rt/h/msg_auto_ptr.hpp>
00013 
00014 #include <so_4/socket/channels/h/channels.hpp>
00015 #include <so_4/rt/comm/h/a_srv_channel.hpp>
00016 
00017 #include <so_4/api/h/api.hpp>
00018 
00019 #include <so_4/timer_thread/simple/h/pub.hpp>
00020 #include <so_4/disp/active_obj/h/pub.hpp>
00021 
00022 #include <so_4/sop/h/filter.hpp>
00023 
00024 #include "c1i.hpp"
00025 #include "c2i.hpp"
00026 
00027 //
00028 // Класс главного агента серверной части.
00029 //
00030 class a_srv_t :
00031   public so_4::rt::agent_t
00032 {
00033   typedef so_4::rt::agent_t base_type_t;
00034   public :
00035     a_srv_t();
00036     virtual ~a_srv_t();
00037 
00038     virtual const char *
00039     so_query_type() const;
00040 
00041     virtual void
00042     so_on_subscription();
00043 
00044     // Имя единственного агента этого типа в приложении.
00045     static const std::string &
00046     agent_name();
00047 
00048     // Реакция на появление агента в системе.
00049     void
00050     evt_start();
00051 
00052     // Реакция на запрос клиента #1.
00053     void
00054     evt_c1_request(
00055       const c1i_t::msg_request * );
00056 
00057     // Реакция на ответ клиента #2.
00058     void
00059     evt_c2_reply(
00060       const c2i_t::msg_reply * );
00061 };
00062 
00063 SOL4_CLASS_START( a_srv_t )
00064 
00065   SOL4_EVENT( evt_start )
00066 
00067   SOL4_EVENT_STC(
00068     evt_c1_request,
00069     c1i_t::msg_request )
00070 
00071   SOL4_EVENT_STC(
00072     evt_c2_reply,
00073     c2i_t::msg_reply )
00074 
00075   SOL4_STATE_START( st_normal )
00076     SOL4_STATE_EVENT( evt_start )
00077     SOL4_STATE_EVENT( evt_c1_request )
00078     SOL4_STATE_EVENT( evt_c2_reply )
00079   SOL4_STATE_FINISH()
00080 
00081 SOL4_CLASS_FINISH()
00082 
00083 a_srv_t::a_srv_t()
00084   :
00085     base_type_t( agent_name() )
00086 {
00087 }
00088 
00089 a_srv_t::~a_srv_t()
00090 {
00091 }
00092 
00093 void
00094 a_srv_t::so_on_subscription()
00095 {
00096   // Подписываем те события, инциденты для которых
00097   // в системе уже существуют.
00098   so_subscribe( "evt_start",
00099     so_4::rt::sobjectizer_agent_name(), "msg_start" );
00100 }
00101 
00102 const std::string &
00103 a_srv_t::agent_name()
00104 {
00105   static std::string name( "a_srv" );
00106   return name;
00107 }
00108 
00109 void
00110 a_srv_t::evt_start()
00111 {
00112   so_4::ret_code_t rc = so_4::api::make_global_agent(
00113     c1i_t::agent_name(),
00114     c1i_t::agent_type() );
00115   if( rc )
00116     std::cerr << rc << std::endl;
00117   else
00118   {
00119     rc = so_4::api::make_global_agent(
00120       c2i_t::agent_name(),
00121       c2i_t::agent_type() );
00122     if( rc )
00123       std::cerr << rc << std::endl;
00124     else
00125     {
00126       // Подписываемся на сообщения глобальных агентов.
00127       so_subscribe( "evt_c1_request",
00128         c1i_t::agent_name(), "msg_request" );
00129 
00130       so_subscribe( "evt_c2_reply",
00131         c2i_t::agent_name(), "msg_reply" );
00132     }
00133   }
00134 }
00135 
00136 void
00137 a_srv_t::evt_c1_request(
00138   const c1i_t::msg_request * )
00139 {
00140   std::cout << "Request from client #1" << std::endl;
00141 
00142   // Нужно отослать запрос клиенту #2.
00143   so_4::api::send_msg( c2i_t::agent_name(),
00144     "msg_request", 0 );
00145 }
00146 
00147 void
00148 a_srv_t::evt_c2_reply(
00149   const c2i_t::msg_reply * )
00150 {
00151   std::cout << "Reply from client #2" << std::endl;
00152 
00153   // Нужно отослать ответ клиенту #1.
00154   so_4::api::send_msg( c1i_t::agent_name(),
00155     "msg_reply", 0 );
00156 }
00157 
00158 int
00159 main( int argc, char ** argv )
00160 {
00161   if( 2 == argc )
00162   {
00163     // Готовимся запустить диспетчер.
00164     std::auto_ptr< so_4::timer_thread::timer_thread_t >
00165       timer_ptr( so_4::timer_thread::simple::create_timer_thread() );
00166 
00167     std::auto_ptr< so_4::rt::dispatcher_t >
00168       disp_ptr( so_4::disp::active_obj::create_disp( *timer_ptr ) );
00169 
00170     // Агент серверного сокета.
00171     so_4::rt::comm::a_srv_channel_t * a_socksrv =
00172       new so_4::rt::comm::a_srv_channel_t(
00173         "a_srv_channel",
00174         so_4::socket::channels::create_server_channel(
00175           argv[ 1 ] ) );
00176 
00177     // Должен быть активным объектом.
00178     a_socksrv->so_add_traits( so_4::disp::active_obj::
00179       query_active_obj_traits() );
00180 
00181     // Агент-сервер.
00182     a_srv_t * a_server = new a_srv_t();
00183 
00184     // Подготавливаем стартовую кооперацию, которая и будет
00185     // выполнять основную работу приложения.
00186     so_4::rt::agent_t * agents[] = {
00187       a_socksrv,
00188       a_server
00189     };
00190     so_4::rt::dyn_agent_coop_t * coop = new
00191       so_4::rt::dyn_agent_coop_t(
00192         "a_srv", agents,
00193         sizeof( agents ) / sizeof( agents[ 0 ] ) );
00194 
00195     // Запускаемся на работу.
00196     so_4::ret_code_t rc = so_4::api::start( *disp_ptr, coop );
00197     if( rc )
00198     {
00199       std::cerr << "start: " << rc << std::endl;
00200     }
00201 
00202     return int( rc );
00203   }
00204   else
00205   {
00206     std::cerr << "sample_filter_server <sock_addr>"
00207       << std::endl;
00208 
00209     return -1;
00210   }
00211 }

Документация по SObjectizer. Последние изменения: Thu Jan 12 10:52:50 2006. Создано системой  doxygen 1.4.6-NO
Hosted by uCoz