Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> удаленный вызов. детали, реализация, архитектура, у темы новое название! 
:(
    Опции темы
boostcoder
Дата 28.10.2010, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



ок.

Добавлено через 3 минуты и 48 секунд
Цитата(mes @  28.10.2010,  09:17 Найти цитируемый пост)
нам важны сейчас две его функции , отправки и приема сырых данных.. 

по приему данных все ок. в коде сервера, в строке 77, заголовок и тело прочитаны. можно диспетчеризировать.

отправку пока оставим в покое я так понял.

сейчас клиента доделаю.
PM WWW   Вверх
mes
Дата 28.10.2010, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  28.10.2010,  08:51 Найти цитируемый пост)
т.е. команды для клиента и сервера разные? не связанные между собой?

при простой модели ( точка <-> точка )  команды симметричны  т.е. что у одного для отправки у другого для приема..

Добавлено через 4 минуты и 10 секунд
Цитата(boostcoder @  28.10.2010,  09:58 Найти цитируемый пост)
Цитата(mes @  28.10.2010,  09:17 )
нам важны сейчас две его функции , отправки и приема сырых данных.. 

по приему данных все ок. в коде сервера, в строке 77, заголовок и тело прочитаны. можно диспетчеризировать.

имелось ввиду что не важен сам процесс отправки, и другие функции такие как подключение..

наш rpc_sender с ресивером могут работать в том числе и без сетевого клиента ( если взаимодействие не через сеть)..
но это опять забегание вперед, для того чтоб немножко снизить туманость на пути к цели smile

Добавлено через 14 минут и 42 секунды
Цитата(boostcoder @  28.10.2010,  09:58 Найти цитируемый пост)
 строке 77, заголовок и тело прочитаны. можно диспетчеризировать.

да, только, чтоб можно было диспатчеризовать кому угодно, и развязать нам руки, вместо  _impl поставить  делегата 
smile


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 28.10.2010, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



код клиента.
только не связал rpc_sender и rpc_receiver, ибо не уверен что все понял..
Код


#include "header.hpp"

/***************************************************************************/

struct rpc_sender {

   std::function<void()> raw_send;
   
   rpc_sender(constants::header_buffer& h, constants::body_buffer& b)
      :_header(h),_body(b)
   {}
   
   template<typename T>
   void send(const T& o) {
      serializer(_header, _body, o);
      raw_send();
   }

private:
   constants::header_buffer& _header;
   constants::body_buffer& _body;
};

/***************************************************************************/

struct rpc_receiver {
   rpc_receiver(constants::header_buffer& h, constants::body_buffer& b)
      :_header(h),_body(b)
   {}

   void dispatch() {
      std::cout << _header.begin() << std::endl;
   }

private:
   constants::header_buffer& _header;
   constants::body_buffer& _body;
};

/***************************************************************************/

struct client {
   client(boost::asio::io_service& ios, const char* ip, boost::uint16_t port)
      :_socket(ios),
      _idx(0)
   {
      boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string(ip), port);
      _socket.connect(endpoint);
      std::cout << "client: connected to server" << std::endl;
      /**  */
      start_read();
   }

   ~client() {
      _socket.close();
      std::cout << "destructing client" << std::endl;
   }

   void start_read() {
      boost::asio::async_read(_socket,
         boost::asio::buffer(_header, _header.size()),
         boost::bind(&client::header_read_handler, this, boost::asio::placeholders::error)
      );
   }

   void raw_send() {
      boost::asio::async_write(_socket,
         boost::asio::buffer(_header, _header.size()),
         boost::bind(&client::header_write_handler, this, boost::asio::placeholders::error)
      );
   }

   void header_read_handler(const boost::system::error_code& e) {
      if ( !e ) {
         /** заголовок прочитан */
         boost::asio::async_read(_socket,
            boost::asio::buffer(_body, header_coders::decode_header(_header).body_length),
            boost::bind(&client::body_read_handler, this, boost::asio::placeholders::error)
         );
      } else {
         std::cout << "client: error read header" << std::endl;
      }
   }

   void body_read_handler(const boost::system::error_code& e) {
      if ( !e ) {
         /** тело прочитано */
         start_read();
      } else {
      }
   }

   void header_write_handler(const boost::system::error_code& e) {
      if ( !e ) {
         /** заголовок отправлен */
         boost::asio::async_write(_socket,
            boost::asio::buffer(_body, header_coders::decode_header(_header).body_length),
            boost::bind(&client::body_write_handler, this, boost::asio::placeholders::error)
         );
      } else {
         std::cout << "client: error on writing to server" << std::endl;
      }
   }

   void body_write_handler(const boost::system::error_code& e) {
      if ( !e ) {
         /** тело отправлено */
      } else {
         std::cout << "client: error on writing to server" << std::endl;
      }
   }

   constants::header_buffer _header;
   constants::body_buffer _body;

private:
   boost::asio::ip::tcp::socket _socket;
   int _idx;
};

/***************************************************************************/

int main() {
   try {
      boost::asio::io_service ios;
      client client(ios, host, port);
      ios.run();
   } catch (const std::exception& e) {
      std::cout << "(exception): " << e.what() << std::endl;
   }
}

/***************************************************************************/



PM WWW   Вверх
mes
Дата 28.10.2010, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  28.10.2010,  10:59 Найти цитируемый пост)
  std::function<void(header&, body&)> raw_send;


Добавлено через 1 минуту и 29 секунд
Цитата(boostcoder @  28.10.2010,  10:59 Найти цитируемый пост)
rpc_receiver {
   rpc_receiver(constants::header_buffer& h, constants::body_buffer& b)
      :_header(h),_body(b)

нет.. 

Код

struct rpc_receiver {
   
   void dispatch(header&, body&) {
      std::cout << _header.begin() << std::endl;
   }



Добавлено через 3 минуты и 11 секунд
выкидываем пока клиента... а то Вас так прям и тянет в сторону ...

Добавлено через 4 минуты и 52 секунды
пишем только сендер и ресивер.. связываем выход сендера, со входом ресивера.. 
при отправке пользователем тпизированного сообщения, ресивер должен распечать его в сыром виде.. 
smile

Добавлено через 5 минут и 54 секунды
т.е связаны должны быть  raw_send и dispatch 
smile



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 28.10.2010, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



вот.
Код


#include "header.hpp"

/***************************************************************************/

struct rpc_sender {

   std::function<void(constants::header_buffer&, constants::body_buffer&)> raw_send;
   
   rpc_sender() {}
   
   template<typename T>
   void send(const T& o) {
      raw_send(...); /** объекты заголовка и тела должны быть локальными? */
   }
};

/***************************************************************************/

struct rpc_receiver {
   rpc_receiver() {}

   void dispatch(constants::header_buffer& h, constants::body_buffer& и) {
      std::cout << р.begin() << std::endl;
   }
};

/***************************************************************************/

struct client {
   client(boost::asio::io_service& ios, const char* ip, boost::uint16_t port)
      :_socket(ios),
      _idx(0)
   {
      boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string(ip), port);
      _socket.connect(endpoint);
      std::cout << "client: connected to server" << std::endl;
      /**  */
      start_read();
   }

   ~client() {
      _socket.close();
      std::cout << "destructing client" << std::endl;
   }

   void start_read() {
      boost::asio::async_read(_socket,
         boost::asio::buffer(_header, _header.size()),
         boost::bind(&client::header_read_handler, this, boost::asio::placeholders::error)
      );
   }

   void raw_send() {
      boost::asio::async_write(_socket,
         boost::asio::buffer(_header, _header.size()),
         boost::bind(&client::header_write_handler, this, boost::asio::placeholders::error)
      );
   }

   void header_read_handler(const boost::system::error_code& e) {
      if ( !e ) {
         /** заголовок прочитан */
         boost::asio::async_read(_socket,
            boost::asio::buffer(_body, header_coders::decode_header(_header).body_length),
            boost::bind(&client::body_read_handler, this, boost::asio::placeholders::error)
         );
      } else {
         std::cout << "client: error read header" << std::endl;
      }
   }

   void body_read_handler(const boost::system::error_code& e) {
      if ( !e ) {
         /** тело прочитано */
         start_read();
      } else {
      }
   }

   void header_write_handler(const boost::system::error_code& e) {
      if ( !e ) {
         /** заголовок отправлен */
         boost::asio::async_write(_socket,
            boost::asio::buffer(_body, header_coders::decode_header(_header).body_length),
            boost::bind(&client::body_write_handler, this, boost::asio::placeholders::error)
         );
      } else {
         std::cout << "client: error on writing to server" << std::endl;
      }
   }

   void body_write_handler(const boost::system::error_code& e) {
      if ( !e ) {
         /** тело отправлено */
      } else {
         std::cout << "client: error on writing to server" << std::endl;
      }
   }

   constants::header_buffer _header;
   constants::body_buffer _body;

private:
   boost::asio::ip::tcp::socket _socket;
   int _idx;
};

/***************************************************************************/

int main() {
   try {
      boost::asio::io_service ios;
      client client(ios, host, port);
      ios.run();
   } catch (const std::exception& e) {
      std::cout << "(exception): " << e.what() << std::endl;
   }
}

/***************************************************************************/


PM WWW   Вверх
mes
Дата 28.10.2010, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  28.10.2010,  11:09 Найти цитируемый пост)
/** объекты заголовка и тела должны быть локальными? */

сейчас да.. после , если захотите избежать лишних копирований, или иметь возможность помещать в очередь ожидания, они пакуются в полиморфный объект (raw_packet) но нам это сейчас лишнее..

Добавлено через 1 минуту и 45 секунд
а посмотрел на клиент.. вы не то связали..  raw_send  не привязывается к клиенту ..

Добавлено через 2 минуты и 17 секунд
т.е. не привязывается как хэндлер записи... 


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 28.10.2010, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  28.10.2010,  12:02 Найти цитируемый пост)
выкидываем пока клиента... а то Вас так прям и тянет в сторону ...

Добавлено через 4 минуты и 52 секунды
пишем только сендер и ресивер.. связываем выход сендера, со входом ресивера.. 
при отправке пользователем тпизированного сообщения, ресивер должен распечать его в сыром виде.. 

т.е. код клиента выкидываем, и в main() связываем только два объекта sender и receiver ?
PM WWW   Вверх
mes
Дата 28.10.2010, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  28.10.2010,  11:16 Найти цитируемый пост)
т.е. код клиента выкидываем, и в main() связываем только два объекта sender и receiver ? 

сейчас да.. чтоб Вы поняли как клиент подключать smile



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 28.10.2010, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



так?
Код

/***************************************************************************/

struct rpc_sender {

   std::function<void(constants::header_buffer&, constants::body_buffer&)> raw_send;

   rpc_sender() {}

   template<typename T>
   void send(const T& o) {
      raw_send(_header, _body);
   }
private:
   constants::header_buffer _header;
   constants::body_buffer _body;
};

/***************************************************************************/

struct rpc_receiver {
   rpc_receiver() {}

   void dispatch(constants::header_buffer& h, constants::body_buffer& b) {
      std::cout << h.begin() << std::endl;
   }
};

/***************************************************************************/

int main() {
   rpc_sender sender;
   rpc_receiver receiver;

   sender.raw_send = boost::bind(&rpc_receiver::dispatch, &receiver);
}

/***************************************************************************/



Это сообщение отредактировал(а) boostcoder - 28.10.2010, 12:34
PM WWW   Вверх
mes
Дата 28.10.2010, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



вобще то так :
Код

struct rpc_sender {
   std::function<void(constants::header_buffer&, constants::body_buffer&)> raw_send;
   rpc_sender() {}

   template<typename T>
     void send(const T& o) {

        constants::header_buffer _header;
        constants::body_buffer    _body;
       
        serializer(_header, _body, o);      
        raw_send(_header, _body);
    }
};




--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 28.10.2010, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



хорошо.
что дальше?
PM WWW   Вверх
mes
Дата 28.10.2010, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



теперь к ресиверу нужно добавить таблицу диспетчеров.. 
где dispacther полиморфно принимает сырой пакет, конвертирует  его в нужный тип, и отдает делегату .. 



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 28.10.2010, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



так?
Код

/***************************************************************************/

struct i_invoker {
   virtual void dispatch(constants::header_buffer&, constants::body_buffer&) = 0;
};
typedef std::shared_ptr<i_invoker> i_invoker_ptr;

template<typename T, typename C>
struct invoker: i_invoker {
   typedef void(C::*handler_t)(T&);

   invoker(C* p, handler_t h):_this(p),_handler(h) {}

   virtual void dispatch(constants::header_buffer& h, constants::body_buffer& b) {
      T data;
      deserializer(data, h, b);
      (*_this.*_handler)(data);
   }

private:
   C* _this;
   handler_t _handler;
};

/***************************************************************************/

struct rpc_sender {
   std::function<void(constants::header_buffer&, constants::body_buffer&)> raw_send;
   rpc_sender() {}

   template<typename T>
   void send(const T& o) {
      constants::header_buffer _header;
      constants::body_buffer _body;

      serializer(_header, _body, o);
      raw_send(_header, _body);
   }
};

/***************************************************************************/

struct rpc_receiver {
   rpc_receiver() {
      /** init */
   }

   virtual void dispatch(constants::header_buffer& h, constants::body_buffer& b) {
      int id = header_coders::decode_header(h).id;
      _map[id]->dispatch(h, b);
   }

private:
   std::map<int, i_invoker_ptr> _map;
};

/***************************************************************************/

int main() {
   rpc_sender sender;
   rpc_receiver receiver;

   sender.raw_send = boost::bind(&rpc_receiver::dispatch, &receiver);
}

/***************************************************************************/


PM WWW   Вверх
mes
Дата 28.10.2010, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



опять не совсем.. слишком рано для предположения о передачи типизированного сообщения ресиверу... ресивер это чать rpc, a сообщения должны обрабатываться в пользовательской части ..
smile

Добавлено через 2 минуты и 45 секунд
Цитата(boostcoder @  28.10.2010,  12:02 Найти цитируемый пост)
struct rpc_receiver {
   rpc_receiver() {
      /** init */
   }
   virtual void dispatch(constants::header_buffer& h, constants::body_buffer& b) {
      int id = header_coders::decode_header(h).id;
      _map[id]->dispatch(h, b);
   }

Код

struct rpc_receiver {
   rpc_receiver() {
      /** не нужен : init */
   }
    /* стереть : virtual */ 
      void dispatch(constants::header_buffer& h, constants::body_buffer& b) {
      int id = header_coders::decode_header(h).id;
      _map[id]->dispatch(h, b);
   }



Это сообщение отредактировал(а) mes - 28.10.2010, 13:11


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 28.10.2010, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



значит так:
Код

/***************************************************************************/

struct i_invoker {
   virtual void dispatch(constants::header_buffer&, constants::body_buffer&) = 0;
};
typedef std::shared_ptr<i_invoker> i_invoker_ptr;

template<typename T, typename C>
struct invoker: i_invoker {
   typedef void(C::*handler_t)(T&);

   invoker(C* p, handler_t h):_this(p),_handler(h) {}

   virtual void dispatch(constants::header_buffer& h, constants::body_buffer& b) {
      T data;
      deserializer(data, h, b);
      (*_this.*_handler)(data);
   }

private:
   C* _this;
   handler_t _handler;
};

/***************************************************************************/

struct rpc_sender {
   std::function<void(constants::header_buffer&, constants::body_buffer&)> raw_send;
   rpc_sender() {}

   template<typename T>
   void send(const T& o) {
      constants::header_buffer _header;
      constants::body_buffer _body;

      serializer(_header, _body, o);
      raw_send(_header, _body);
   }
};

/***************************************************************************/

struct rpc_receiver {
   rpc_receiver() {}

   void dispatch(constants::header_buffer& h, constants::body_buffer& b) {
      int id = header_coders::decode_header(h).id;
      _map[id]->dispatch(h, b);
   }

private:
   std::map<int, i_invoker_ptr> _map;
};

/***************************************************************************/

int main() {
   rpc_sender sender;
   rpc_receiver receiver;

   sender.raw_send = boost::bind(&rpc_receiver::dispatch, &receiver);
}

/***************************************************************************/



Цитата(mes @  28.10.2010,  13:10 Найти цитируемый пост)
слишком рано для предположения о передачи типизированного сообщения ресиверу... ресивер это чать rpc, a сообщения должны обрабатываться в пользовательской части ..

не понимаю к чему это сказано....
PM WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1438 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.