Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > удаленный вызов. детали, реализация, архитектура |
Автор: boostcoder 6.10.2010, 11:23 | ||||||
всем доброго дня. имеем тип T:
в runtime мы получаем id`ы. хочу реализовать что-то вроде типозависимого прокси callable`ра(хз как правильно назвать). сигнатура методов/объектов такая:
нужна возможность регистрировать методы/объекты имея в runtime только id, и ин compile_time T::id. т.е. зная T::id ат compile_time и id в runtime, назначать методы/объекты принимающие соответствующие им типы. пример конечного использования:
как-то так... запутался, и ничего в голову не лезет... |
Автор: mes 6.10.2010, 11:46 |
это разные числа , или одно и то же ? |
Автор: boostcoder 6.10.2010, 17:19 |
если id == type1::id, то должен произойти вызов method1(...) int id имеет диапазон type1::id ... typeN::id два уточнения: 1. typeN::id - это enum. так что можно использовать в mpl. 2. у всех typeN общий предок. |
Автор: mes 7.10.2010, 01:02 |
было б лучше если б дали немного сведений и о задачи, а именно какие требования предъявляются к рантайм.. вот на полусне : http://liveworkspace.org/code/c8cf16a805aa19cb10bc837af0545038 в том хоть направлении ? Добавлено через 3 минуты и 27 секунд это Вы удаленный вызов реализуете ? Добавлено через 5 минут и 19 секунд а что ж тогда не объект класса typeN передается ? |
Автор: maxim1000 7.10.2010, 08:44 |
в параметрах должны быть типы или значения соответствующих типов? |
Автор: boostcoder 7.10.2010, 08:50 | ||
да. похоже на то. покурю... можно и тип. но задача не упростится. я для пользователя удобней и понятней.
значения. |
Автор: mes 7.10.2010, 09:24 | ||
при использовании структуры кол-во аргументов функции постоянно. |
Автор: mes 7.10.2010, 15:48 | ||
так же удобство структуры в возможности легкой (мета ориентированной) регистрации , т.е. для неперегруженных функций достаточно только передать имя функции :
подправленная версия : http://liveworkspace.org/code/3b42cd08948eddfa684cf01e63c3374e |
Автор: maxim1000 8.10.2010, 00:10 |
можно упаковывать полученные аргументы в boost::any а методы оборачивать во что-то шаблонное, унаследованное от общего интерфейса (который и принимает эти boost::any) Добавлено через 55 секунд (правда, не получится пользоваться неявными преобразованиями) |
Автор: mes 8.10.2010, 09:40 |
в примере обработчиками выступают функции, но у конечному пользователь захочется иметь что либо более универсальное..поможет класс Dispatchera, для конвертации параметра и класс функции (напр boost::function) http://liveworkspace.org/code/09b6daf1e59dd1131aee0c15a1aff76d на "ляпы" не относящиеся к сути проблемы (такие как неподходящий способ хранения) внимания не обращать ![]() |
Автор: mes 8.10.2010, 22:23 |
кстати вспомнил, goldfinch одно время на форуме разбирал темы связанные с удаленными вызовами.. не помню к чему он там конкретно пришел, но думаю Вам будет тематически полезно ознакомиться с этим материалом.. если найдете прикрепите ссылки к теме, плиз ![]() |
Автор: boostcoder 9.10.2010, 03:12 |
я даже аккаунта такого не могу найти. и функцию поиска аккаунтов тоже :( пока курю ваш пример. хочется автоматизировать это все. написать кодогенератор на препроцессоре - не проблема. но есть несколько неудобных моментов. думаю... |
Автор: boostcoder 9.10.2010, 07:15 | ||||||
mes, сделал так, как вы предложили:
используется это дело так:
метод proxy_caller::call() вызывается из сетевой части после того, как буфера на которые ссылается proxy_caller заполнены. как видно из реализации метода methods_dispatcher::dispatch(), ответ отправляется обратно при выходе из тела этого метода. не худшая реализация RPC из тех что я видел ![]() но хочется большего. а именно: скрыть от юзера все, кроме самого implementation. в идеале, цель хочу видеть такой:
но тут есть непонятка... т.к. клиент, всего лишь дергает методы сервера, ему их реализация не нужна. но она нужна серверу. вот и непонятка: что на самом деле нужно на стороне клиента, чтоб дергать методы сервера? и что нужно знать серверу, чтоб понять, какой именно метод вызывает клиент? |
Автор: mes 9.10.2010, 10:44 |
ну проще было искать тему, и поставить ограничение по юзеру.. вобщем вот об этой я говорил : http://forum.vingrad.ru/forum/topic-269086/unread-1/hl/remote/index.html#st_0_view_0 |
Автор: boostcoder 9.10.2010, 10:52 |
почитал. но в теме не нашел ничего полезного касательно реализации. а готовое не устраивает по ряду причин, обсуждать которые нет желания. |
Автор: mes 9.10.2010, 10:54 |
да, я тоже прочитал, по старой памяти думал там больше полезного ![]() Добавлено @ 11:03 вот например метод login... напишите отдельно, как Вы представляете, клиентскую и серверную часть функционала не затрагивая реализацию rpc, т.е. фактически конечные точки Вашей схемы. |
Автор: boostcoder 9.10.2010, 11:23 |
mes, а что именно описать? как это все происходит сейчас? или что?... метод login - просто метод. вызывая его на стороне клиента, его аргументы отправляются на сервер, десериализуются, вызывается назначенный для этого типа запроса обработчик, тот в свою очередь получает дополнительный аргумент по ссылке в который кладет ответ, ответ сериализуется, отправляется клиенту, клиент десериализует его, и возвращает юзеру объект типа ответа. |
Автор: mes 9.10.2010, 11:34 | ||||||
имелся ввиду код взаимодействия.. как Вы его видите.. например так :
Добавлено @ 11:37
это как раз лишнее, так как |
Автор: boostcoder 9.10.2010, 11:44 | ||||
понял. вот нынешний реальный код на стороне клиента. он даже работает ![]()
client::query<>() возвращает смарт-поинтер. Добавлено через 2 минуты и 25 секунд
что-то у меня это по удобнее получилось ![]() Добавлено через 4 минуты и 21 секунду на стороне сервера, каждый тип команды, ассоциирован с методом обработчиком. |
Автор: mes 9.10.2010, 11:49 |
первое что бросается в глаза, value_type не очень удачное название.. |
Автор: boostcoder 9.10.2010, 11:51 |
mes, почему? как тогда его лучше назвать? мне многие названия в моем коде не нравятся, наверное фантазии не хватает) |
Автор: mes 9.10.2010, 11:51 |
второе, что у Вас не ассинхронный обмен - так и нужно ? |
Автор: boostcoder 9.10.2010, 11:53 |
асинхронный до тех пор, пока не вызывается один из методов value_type. иначе, вызывающий поток приостанавливается на время получения ответа от сервера. только еще нужно таймаут прикрутить. |
Автор: mes 9.10.2010, 11:55 | ||
как не знаю.. просто за value_type уже закрепилось некоторое смысловое значение, которое не совпадает с приведенным применением.. ну например response_type или return_type .. Добавлено через 2 минуты и 36 секунд не до конца понял.. запрос к серверу идет здесь
или здесь ? |
Автор: boostcoder 9.10.2010, 11:58 |
да, так лучше. |
Автор: mes 9.10.2010, 11:59 |
т.е. ассинхронность введена специально ? или все ж так получилось ? Добавлено через 4 минуты и 43 секунды ну так не удивительно.. я то написал спонтанно ![]() |
Автор: boostcoder 9.10.2010, 12:07 | ||||
здесь:
он ставится в очередь на основе boost::thread + asio::io_service + boost::packaged_task<> но при вызове любого из методов результата, вызывается boost::unique_future::get(), который приостанавливает вызывающий цикл. Добавлено @ 12:08 да, специально. Добавлено @ 12:14 хотя в этом есть некоторое не очевидное поведение: если вдруг asio::io_service::run выполнить в нескольких потоках(типа пул потоков), и сделать один запрос к серверу ничего не возвращающий но сохраняющий в объект сессии некоторое значение, и следом за ним сделать запрос получающий это значение, то может получится так, что второй запрос придет на сервер раньше ![]() чтоб исключить такую ситуацию, в тип нужно добавить служебный метод, что-то типа wait(). сделаю... позже.. Добавлено @ 12:19
|
Автор: boostcoder 9.10.2010, 12:41 | ||
собственно сейчас меня интересует, каким образом можно авторегистрировать методы-обработчики на стороне сервера, учитывая такую структуру:
http://liveworkspace.org/?id=bb4bddf94368b5924b96872fa347ec98 connection - объект сессии с клиентом. |
Автор: mes 9.10.2010, 12:41 | ||||
интуитивно напрашивается такой псевдо-код :
где rpc это шаблонная структура обертка, отвечающая за отправку запроса клиенту, ожидание и предоставления доступа к результату. Добавлено через 3 минуты и 6 секунд
не приглядывался но мне кажется вы хотите, чтоб у сервера на все пакеты были перегруженные функции с одним именем.. тогда вам поможет список_типов.. |
Автор: boostcoder 9.10.2010, 12:46 | ||||||
для этого, нужен метагенератор, генерирующий метаинформацию из к примеру, такого макроса:
если принять за правило соответствие деклараций методов в этом макросе и в реализации этого класса на стороне сервера, то задача кажется вполне выполнимой. т.е. для этого интерфейса должна быть такая реализация:
есть идеи? Добавлено через 4 минуты и 44 секунды вариант. еще вариант, сделать так, чтоб ожидание происходило в деструкторе типа ответа. т.к. он в смарт-поинтере, если мы не приаттачились к нему, то в деструкторе ждать.
нет. на каждый тип команды свой метод обработчик на сервере. |
Автор: mes 9.10.2010, 12:52 |
в данном случае не понял идеи чего нужны... как из макроса генерить описание серверного обработчика ? сообщение про список типов видели ? если приведете функции обработчики к одному имени, то выгадаете (не кодогенеруеммую, а шаблонную) автоматизацию ![]() естественно разный, но с таким же именем )) |
Автор: boostcoder 9.10.2010, 12:54 | ||
![]() я не очень представляю, что именно макрос должен сгенерировать, чтоб без реализации на стороне клиента слинковать программу, а на стороне сервера понять что к чему и как вязать. Добавлено через 2 минуты и 48 секунд что имеется в виду? Добавлено через 5 минут и 26 секунд имена у них тоже разные:
|
Автор: mes 9.10.2010, 13:13 | ||||
у буста что то в этом роде :
ну а сервер выглядит так
|
Автор: boostcoder 9.10.2010, 13:19 | ||
т.е. вы предлагаете решение, в котором для идентификации методов используется список типов аргументов? я правильно Вас понял?
неудобно тем, что имена одинаковые. разобрать аргументы метода на список типов, и собрать их обратно - не проблема. проблема именно в имени метода. |
Автор: mes 9.10.2010, 13:25 | ||||||
фактически именем метода будет выступать имя типа пакета.. а чем неудобно одинаковое имя ? Добавлено через 51 секунду
да список типов будет определять какие обработчики предоставляет сервер. Добавлено через 1 минуту и 58 секунд
а вот разбирать ничего не надо.. типы должны задаваться интерфейсом, который вы кодогенерируете.. Добавлено через 2 минуты и 50 секунд не обязательно напрямую, возможно через прослойку, только внешне не видную. Добавлено через 4 минуты и 56 секунд сейчас еще одна идея пришла... надо обдумать.. |
Автор: boostcoder 9.10.2010, 14:11 |
имел в виду их и разобрать. пока не представляю, что должно генерироваться на стороне клиента, чтоб прога скомпилилась.. на стороне сервера - понятно, из сгенерированного кода берется информация необходимая для связывания указателя на объект реализации интерфейса с которым должна связываться. |
Автор: mes 9.10.2010, 14:33 | ||
клиент заканчивается отправкой сериализированного объекта в _сокет_. Добавлено через 1 минуту и 30 секунд хотя да.. я забыл что еще ответ надо ждать.. вот тут есть проблемка... |
Автор: boostcoder 9.10.2010, 14:45 | ||
угу. но вроде как можно приблизительно так(мысли в слух): на стороне клиента, сгенериный интерфейс используется совместно с классом client<interface> на стороне сервера, сгенериный интерфейс используется совместно с классом server<interface> то что генерится, должно содержать в себе какое-то значение времени компиляции которое client<> и server<> будут читать, то можно реализовать их таким образом, чтоб каждый брал для себя только то, что ему нужно. клиенту, на самом деле, нужны эти методы реализованными, но тело этих методов должно посылать запрос на сервер, содержащий в себе помимо самого запроса, еще и информацию идентифицирующую запрос. тогда сервер сможет понять чего от него хотят. серверу, нужна полная реализация, методы которой, вызываются из оберток. как-то так... |
Автор: boostcoder 9.10.2010, 15:07 | ||||
даже не так... получается так, что оба используют сгенериный интерфейс только для того, чтоб иметь дополнительную информацию о вызове. к примеру:
и возвращаемся к старому вопросу: 1. что должен генерировать метагенератор на стороне клиента? 2. что должен генерировать метагенератор на стороне сервера? 3. как связать сгенерированную информацию с реальным, написанным нами, классом? |
Автор: mes 9.10.2010, 15:20 |
тоже мысли вслух.. у нас есть запрос мы отправляем его серверу, от него получаем ответ.. тут нужна гарантия определения к какому запросу этот ответ 1. либо у нас строгая очередность, и нет следующего запроса пока не получет ответ. имхо, не имеет смысла 2. запрос сохраняется и выделяется уникальный нумер операции т.е. тогда возможны два запроса подряд одного типа. 3. каждый вид запроса может существовать только в единственном экземпляре.. но тут опять видна несогласованность, ответ может придти на предыдущий запрос, который мы отменили.. Добавлено через 4 минуты и 45 секунд насчет сервера... у нас есть некий компонент, который локально выполняет некую работу.. мы должны определить связку между запросом и компонентом.. т.е. на каждый тип запроса у нас должен быть бинд забирающий инфу откомпонента.. по идеи значит надо для диспетчера создать таблицу лямб функций возвращаюших ответ, на запрос.. Добавлено через 5 минут и 18 секунд ну так и получается, что имя функции нам не нужно.. |
Автор: boostcoder 9.10.2010, 15:26 | ||
так и запланировано. выше, я просто привел пример, каким образом можно получить неочередность. а так как запросы живут в одном io_service, то все они выполняются строго в том порядке, в каком были добавлены в очередь. |
Автор: mes 9.10.2010, 15:30 | ||
т.е. в сеть не отправляется ничего, до тех пора пока не получен ответ ? имхо не рационально .. |
Автор: mes 9.10.2010, 17:38 |
кстати при подобной архитектуре сервер получается пассивным, т.е. сообщает только ту информацию которую запросил клиент.. однако судя по названиям некоторых типов Вы разрабатываете нечто вроде чата/игры.. В подобных случаях очень часто бывает необходимость, о сообщение клиенту деталей без его запроса.. |
Автор: boostcoder 9.10.2010, 20:25 | ||||||||||
да. я понимаю, что можно запросам присваивать ID`ы. но это пока не главный вопрос. Добавлено через 3 минуты и 18 секунд
да.
можно реализовать следующим образом: в client<> добавить deadline_timer, который сам будет слать серверу запросы, и при получении ответов, вызывать некоторый обработчик. но и это не главное.
|
Автор: mes 9.10.2010, 20:58 | ||||
имхо вопрос не с той стороны задан.. для начала нужно представить модель, а как потом это все запихнуть в кодогенерацию дело техники ![]() Добавлено через 39 секунд т.е. для начала надо представить как будет выглядить код.. Добавлено через 1 минуту и 17 секунд итак Вы решили (с чем я не согласен) что синхронность будет удобнее.. Добавлено через 2 минуты и 12 секунд тогда у нас есть rpc::client, к которому мы можем посылать запросы и получать ответ Добавлено через 3 минуты и 48 секунд выполнение запроса все равно будет проходить в паралельном потоке, поэтому мы можем чем нибудь себя занять, но при этом должны уметь контролировать состояние запроса .. Добавлено через 4 минуты и 44 секунды тогда при отправке запроса, мы должны получить некую структуру контроллера-наблюдателя.. Добавлено через 8 минут и 32 секунды допустим это будет выглядить так :
Добавлено через 9 минут и 45 секунд отвлекемся на сервер .. |
Автор: mes 9.10.2010, 21:14 | ||||
сервер хранит модель и список клиентов (сокетов) которые хотят ее изменить.. объект сервера выступает своего рода контроллером этих взаимодействий тогда
Добавлено @ 21:16 теперь нам необходимо как то зарегистрировать функции можно сделать массив/карту делегатов и связать их, Добавлено @ 21:21 а можно отделить внутренности сервера от методов обработчиков .. тогда вместо методов обработчиков определяем таблицу вызовов и тогда регистриуемая функция будет иметь вид
естественно вместо самих функций моно использовать лямбды.. но чтоб не сбиваться идем простым путем.. |
Автор: boostcoder 9.10.2010, 21:27 | ||
нет. асинхронность можно реализовать. просто в данный момент мне это не кажется первостепенной задачей. пишу мысли... минутку.. |
Автор: mes 9.10.2010, 21:27 | ||
итого значит сервер представлен у нас списком клиентом, контекстом/моделью/сессию (что нагляднее) и таблицей "виртуальных " функций.. заполнять таблицу и задавать модель должен разработчик, сам сервер должен быть представлен библиотекой, ну а таблица по идеи генериться кодогенератором .. Добавлено @ 21:30 итого значит у нас есть rpc::server и rpc::client (не пустать с rpc::server::client ) осуществляющие связь посредством сырых данных и взаимодействующие с пользователем типизированным пакетами. Добавлено @ 21:36 т.е общий код выглядит так
Добавлено через 9 минут и 58 секунд писал rpc::login но по сути пакеты должны находится в другом неймспейсе, например название протокола.. Добавлено через 11 минут и 7 секунд все.. вроде свои мысли высказал.. |
Автор: boostcoder 10.10.2010, 01:54 | ||||
вот как я вижу модель: в данный момент, для каждого входящего соединения(т.к. клиенты сначала подключаются к серверу), создается объект, указанный в типе шаблона сервера. таким образом, получается так, что каждый клиент общается со своим собственным объектом. при завершении сеанса, объект удаляется. есть еще вариант, инициализировать объект сервер, ссылающимся на общий для всех клиентов объект. в таком случае, так как объект реализует кодер, то синхроннизация/разделение_доступа ложится на него.
тогда, в дополнение, было бы мегаудобным, реализовать в классе client<> запрос, типа create_session<type>(). который будет на стороне сервера создавать объект сессии, и переключать контекст клиента на этот объект. если пойти немного дальше, то класс server<> можно реализовать так, чтоб список шаблонных аргументов был переменным. в таком случае, клиент, может делать запросы на создание какого-то конкретного объекта сессии, и пользоваться им.
но это все потом. сейчас первостепенный вопрос в том, какие данные должен генерировать кодогенератор чтоб клиент и сервер могли автосвязывать запросы/ответы с методами/реализацией? |
Автор: mes 10.10.2010, 09:37 | ||||||
но насколько я понял, у вас к примеру есть комнаты, в которые могут зайти разные клиенты, а значит сессия (или ее контекст) не у каждого своя а разделяемая(shared).
детали реализации действительно лишние.. как удобнее сделать, будет видно при кодировании.. главное разобраться с сутью взаимоотношений.
на мой взгляд достаточно только генерации пакетов, и списка типов пакетов. клиент и сервер должны быть целыми (не кодогенерируемыми) шаблонами. Добавлено @ 09:39 список типов определяет какими сообщениями они могут обмениваться, а также для для сервера служит основой для таблицы регистрации.. Добавлено @ 09:44 как выглядит пакет и какие данные он должен содержать зависит от клиента и сервера.. поэтому имхо первостепенный вопрос стоит не в кодогенераторе, а в проектирование конечных точек соединения.. при том для упрoщения можно реализовывать в одной проге и передавать данные напрямую, как в начале темы через функции типа void call(id, void*); |
Автор: boostcoder 11.10.2010, 02:36 | ||||||||
сессия - контекст пользователя/соединения. комнаты - некоторые объекты, взаимодействие с которыми происходит посредством сессий.
наверное я вас не понимаю.. поясните пожалуйста. немного пораздумав.. должно получиться как-то так:
сервер:
|
Автор: mes 11.10.2010, 10:42 |
ловите в упрощенном виде : http://liveworkspace.org/code/bbc75134b93c68f00914597f9c23e38b с односторонним обменом клиент->сервер rpc - библиотека конечных точек взаимодействия ptcl -(кодогенерируемый) протокол обмена my_server - оболочка реализующая поведение сервера (может быть определена как неймспейсом, так и классом) ну и в глобальном пространстве условных запуск трех программ, сервера и двух клиентов.. |
Автор: boostcoder 11.10.2010, 10:48 |
mes, большое спасибо ![]() сейчас буду разбираться. зы на liveworkspace работает табуляция в коде. еще Ctrl+G, Ctrl+F, Ctrl+R, Ctrl+Z. оцените ![]() |
Автор: mes 11.10.2010, 10:50 | ||
![]()
даже не ожидал ! учту, спасибо ) |
Автор: mes 11.10.2010, 11:10 |
и я еще раз насчет (а)синхронности... мне кажется вместо классического вызова функций с получением ответа, где сервер выступает в пассивной форме, удобнее было бы воспользоваться системой взаимообмена сообщений, тогда клиент будет обладать такой же таблицей методов, как и сервер а пакеты разделяться на две группы (client_to_server, server_to_client); |
Автор: boostcoder 11.10.2010, 11:11 | ||
да. согласен. это хороший вариант. |
Автор: boostcoder 25.10.2010, 23:41 | ||
продолжим-с... что у меня есть сейчас:
этот код генерит метагенератор. юзеру остается унаследоваться от этого класса, и реализовать чистовиртуальные методы. как видно, для каждой команды свой метод обработчик. не плохо.. недостаток в том, что пока что, сервер строго привязан типом шаблона. полагаю, сейчас нужно реализовать динамическое создание классов-обработчиков. идея такая: метегенератору указывать имя метаконтейнера который он должен сгенерить помимо класса. и когда юзер запрашивает создание объекта некоторого типа, сервер в метаконтейнере выискивает этот тип. на этом мои мысли исчерпываются.. mes, вы в теме? ![]() |
Автор: mes 26.10.2010, 11:28 | ||
не до конца понятно о чем тут.. над кодом сейчас подумаю.. но сразу чувствуется, что пока это не то что надо .. |
Автор: boostcoder 26.10.2010, 11:33 | ||
вот:
но это плохая реализация. нелепо как-то, в один интерфейс пихать сотни методов ![]() |
Автор: mes 26.10.2010, 11:38 | ||
понял.. Вы о том что у сервера только один исполнитель... ага.. это не то.. но по этому поводу у мя вопрос : исполнители должны иметь каждый свою группу сообщений или некоторые сообщения будут для исполнителей общие ? |
Автор: boostcoder 26.10.2010, 11:51 | ||||
у каждого свои сообщения + общие. общие, это: я хочу реализовать переброс исключений со стороны сервера клиенту. возможно еще какие-то технические данные. еще момент. проблема с конструкторами исполнителей. каким образом реализовать поддержку аргументов для конструкторов? Добавлено через 2 минуты и 15 секунд сейчас приведу структуру классов для понимания.. Добавлено через 12 минут и 20 секунд
где IF - тип исполнителя. |
Автор: mes 26.10.2010, 12:11 | ||||
опять на помню, может уговорю пересмотреть контракт с сервером с запрос->ответ, на вызов<->вызов ![]()
оставить создание исполнителя на стороне пользователя.. Добавлено через 42 секунды как вариант передавать библиотеке ссылку на фабрику.. Добавлено через 3 минуты и 18 секунд итак для начал нам нужно ограничить проблему.. что мы имеем ? набор некоторых типов данных с ид набор исполнителей нам надо доставить данные нужному/нужным исполнителям.. алсо нужно предусмотреть таблицу соответсвий, желательно статическую по отношению к исполнителям.. |
Автор: boostcoder 26.10.2010, 12:18 |
я пока что не представляю как это должно выглядеть/функционировать.. на самом деле, я понимаю, что то, каким образом сейчас происходит общение - это тупик. но не понимаю я как это должно функционировать ![]() поясните плиз ;) да, вариант.. набросаю пример.. |
Автор: mes 26.10.2010, 12:19 |
не торопитесь с этим .. Добавлено через 12 секунд сейчас |
Автор: boostcoder 26.10.2010, 12:21 | ||
кстати. так же, было бы шикарно, реализовать возможность передавать серверу аргумент для исполнителя при запросе его создания.
![]() |
Автор: mes 26.10.2010, 12:38 | ||
Ваша схема (если убрать все лишнее) выглядит так :
главный недостаток в том, что сервер предоставляет информацию ТОЛЬКО по запросу пользователя.. то есть например сообщения чата, будут читаться только когда пользователь запросит, а сервер должен их хранить все это время... а не тогда когда кто то написал.. |
Автор: xvr 26.10.2010, 12:42 | ||
|
Автор: mes 26.10.2010, 12:46 | ||||
а вот так примерно выглядит схема вызов<->вызов :
Добавлено @ 12:48
не знаю как в там в DCOM, но фактически асинхронные callback`и я и предлагаю.. ![]() только вот НЕ с соотношением один вызов один каллбяк ) |
Автор: boostcoder 26.10.2010, 12:50 |
что-то не въезжаю.. откуда на стороне клиента может взяться сервер, и на стороне сервера клиент? кто тогда является сервером? |
Автор: mes 26.10.2010, 12:51 | ||
правда справедливость названия каллбяков в данном случае условна и зависит от способа рассмотрения.. Добавлено @ 12:52
есть локальный сервер и удаленный ![]() Добавлено @ 12:52 с клиентом то же самое ) Добавлено @ 12:59 boostcoder, в общем чтоб не путаться если информация содержится/накапливается на сервере а клиент ее должен считать, то Ваш способ подходит если нужна возможность непосредственного взаимодействия клиента с клиентами или ж просто нужна возможность уведомления от сервера в независимости от запроса клиента то не подойдет. |
Автор: xvr 26.10.2010, 13:00 |
Один в один с твоим предложением ![]() Оба. Равно как и клиентом, тоже оба. |
Автор: boostcoder 26.10.2010, 13:06 | ||
да, собирался реализовать обратные колбэки от сервера клиенту. так что нужно. т.е. чтоб скомпилить клиентскую сторону, должна быть доступна реализация сервера, и на оборот? я правильно понял? |
Автор: mes 26.10.2010, 13:09 | ||
вот например фирма выполняет заказ.. она в этот момент сервер, а заказчик клиент, а когда фирма высылает ему счет для оплаты, то заказчик сервер, а фирма клиент ![]() т.е. все зависит от темы рассмотрения.. ![]() Добавлено @ 13:11
не совсем так.. клиентский клиент и клиентский сервер, несколько (а может и совершенно) другие чем серверный сервер и серверный клиент ![]() ![]() Добавлено @ 13:11 все зависит от исполнения.. ![]() Добавлено @ 13:14 boostcoder, вот с точки зрения основной идеи вашей программы, (не знаю что там но допустим чат) сервер будет сервером вашего чата, а клиент, клиентом вашего чата, но и тот и другой могут иметь серверы удаленых вызовов.. |
Автор: boostcoder 26.10.2010, 13:26 |
т.е. мне нужно сейчас разделить реализацию сервера и клиента на две части. сервер: 1. класс с аксэптором слушающим порт(КАСП). 2. класс взаимодействующий с сокетом клиента(КВСК). клиент: 1. класс взаимодействующий с сокетом сервера(КВСС). 2. сериализатор/десериализатор команд(СДК). мысли в слух.. на стороне сервера создаем объект КАСП и СДК. КАСП используется по назначению, в то время, как СДК используется для реализации обратных вызовов клиента. на стороне клиента создаем объект КВСС и КВСК. КВСС используется по назначению, в то время, как КВСК используется запутался.. Добавлено через 55 секунд в таком случае, нужно два соединения? одно клиента-с-сервером, второе сервера-с-клиентом? так? |
Автор: mes 26.10.2010, 13:29 |
сокет-соединение ? нет одно .. остальное еще не прочел Добавлено @ 13:33 я б сказал не так : есть сокет соединение есть rpc соединение и само исполнение естессвенно у каждого модуля(сервер или клинт) своя реализация каждого уровня.. общие только библиотеки.. |
Автор: boostcoder 26.10.2010, 13:53 |
..не понимаю.. может обратные вызовы реализовать следующим образом: у клиента добавить метод типа "set_callback(int id, function)", где id - идентификатор колбэка, function - объект указывающий на функцию/метод на стороне клиента который будет вызываться. т.е. при вызове set_callback() указанный идентификатор регистрируется на сервере. в то время, на сервере добавить метод типа "callback(id, args...)". где id - идентификатор вызываемого на стороне клиента метода. клиент в свою очередь, должен уметь отличать ответы сервера на свои запросы, от вызовов колбэков. как такая идея? |
Автор: mes 26.10.2010, 14:39 | ||||||||||||||
и так у нас есть как клиент так и сервер могут отправлять вызовы т.е. каждый из них является то отправителем то получателем.. поставленная задача: распределять сообщения по исполнителям.. на тек момент одно сообщение, один исполнитель.. предполагается, что набор исполнителей представляют собой один композиционный объект допустим есть такие сообщения :
такой набор исполнителей
диспетчера сообщений :
условный сервер приемки сообщений
отправитель :
тестовый пример :
и вывод
http://liveworkspace.org/code/5afd22007254aa466ad429549e89fe69 Добавлено через 1 минуту сейчас попробую доработать, чтоб одно сообщение могло в нескольких местах отрабатывать.. |
Автор: mes 26.10.2010, 15:05 | ||
чего то заклинил, можно ведь вместо карты(массива) диспетчеров просто сделать мультикарту.. ![]() |
Автор: boostcoder 26.10.2010, 15:23 | ||||
знаков препинания не хватает..смысла не понял... Добавлено через 25 секунд
ага Добавлено через 55 секунд по остальному - вникаю в суть... |
Автор: mes 26.10.2010, 15:27 | ||
Добавлено через 1 минуту и 35 секунд т.е. приведенный код будет как на севере, так и на клиенте, только для своих групп сообщений |
Автор: boostcoder 26.10.2010, 15:44 | ||||
ага. понял... щас.. |
Автор: mes 26.10.2010, 15:52 | ||||||
или отделить функциональный вызов от диспатчеризации т.е. вместо макроса DEF_DISP и всего с его участием, пишем что то типа такого :
могут быть ошибки.. с лямбдами пока еще не приходилось работать.. |
Автор: mes 26.10.2010, 18:01 |
вот доработал немного : http://liveworkspace.org/code/17eb2d53ecbbf51755b334c82dbf190e Добавлено @ 18:11 а вот чистый пример, без классов исполнителей.. http://liveworkspace.org/code/6e7e20117c8516fd84e7a337ac958087 Добавлено @ 18:13 вот пока объяснял сам разобрался как происходить должно... ![]() если что осталось непонятным, спрашивайте ![]() |
Автор: boostcoder 26.10.2010, 19:50 |
последними двумя примерами, вы меня окончательно запутали.. я так понял, что сейчас мы решаем ассоциирование команд с разными интерфейсами? или что? до этого, я думал что сейчас мы решаем как создавать исполнителей на стороне сервера по запросу клиента. а до этого, думал что мы решали каким образом реализовать колбэки. и это все за один день ![]() |
Автор: mes 26.10.2010, 20:20 | ||||||
так по сути там то же самое.. просто лишние детали выкорчивались..
да вначале решалась задача как доставить сообщение конкретному исполнителю.. потом встала цель перенаправления одного сообщения нескольким исполнетелям, после чего обнаружилось, что исполнителей как таковых может не быть, как частный случай реализации.. ну а в последнем убрал контекст исполнителей чтоб выделить суть. Добавлено через 1 минуту и 9 секунд
исполнители, это пользовательская часть и серверу она если и нужна, то только для связки с сообщениями.. Добавлено через 1 минуту и 49 секунд
и это то же.. как подзадачу ![]() Добавлено через 3 минуты и 24 секунды сейчас надо определиться с какой стороны идти.. |
Автор: boostcoder 26.10.2010, 20:28 |
mes, я вам очень благодарен..но дело в том, что я и в правду запутался. если вас не затруднит, опишите пожалуйста, какой вы видите реализацию, словами. для дурака так сказать. очень благодарен вам за то что вы на протяжении всей темы помогаете мне. спасибо. |
Автор: mes 26.10.2010, 20:34 | ||
это я понял.. поэтому и написал : вот сижу и думаю, с чего начать, что у вас уже есть, и где возникла путаница... Добавлено @ 20:42 ну например клиент может выглядить так :
тут есть вопросы ? пояснения : my_protocol это traits- структура, содержащая список сообщений, допустимых для передачи по соединению.. register() - установка делегата оператор << - отправка сообщения в сеть у меня сейчас похожая задача решается.. так что получилось, что не только Вам, но и себе опыта набираю.. ![]() |
Автор: boostcoder 26.10.2010, 20:49 |
сейчас есть рабочая реализация сервера и клиента, позволяющая декларировать в удобном(абстрактном) для пользователя синтаксисе команды запросов/ответов + генератор всей подноготной необходимой серверу чтоб знать, какая команда с каким обработчиком ассоциирована. первым и очевидным недостатком текущей реализации является то, что сервер привязан к конкретному классу обработчиков. и не имеет возможности в рантайме их менять/создавать. второй недостаток, это то, что нет нормальной реализации обратных колбэков. приоритеты возможно не в том порядке, т.к. возможно одно зависит от другого. вот. |
Автор: mes 26.10.2010, 20:51 | ||||
ну для начала нам достаточно одной, двух комманд чтоб проверить в действии. а уж потом, стоит это поднаготную запаковывать ![]() Добавлено через 44 секунды
т.е. с приемом/передачей одного сообщения у вас проблем нет ? |
Автор: boostcoder 26.10.2010, 20:58 | ||||||||
под обработчиком подразумеваю это:
т.е. это конечный код генерируемый метагенератором. на стороне сервера используется так:
на стороне клиента:
вот. вроде ничего не упустил. Добавлено @ 21:01 не только одного. многих. вот реальный пример теста:
зы у меня есть приватное SVN хранилище, может быть дать вам доступ? это значительно облегчит понимание. |
Автор: mes 26.10.2010, 21:09 |
вот опять вернулись к самому началу.. вы все время избегаете этого факта.. для создания синхроного запрос/ответ вы идете на искусственные ограничения... если нужна будет синхронность ее лучше организовать внешним слоем... я все ж настаиваю на системе вызов<->вызов, так как с каждой минутой все более уверен, что именно она вам нужна.. мне кажется что Вам просто жаль усилий уже потраченных на кодогенератор, поэтому не хотите взглянуть по сторонам.. Добавлено через 3 минуты и 18 секунд для начала все ж дождусь ответа, готовы ли следовать предложеной схеме и отказаться от своей ? |
Автор: boostcoder 26.10.2010, 21:14 | ||
я ведь не спорю. просто я не могу понять что именно вы подразумеваете под этим. как это должно выглядеть? потому я писал выше, что запутался в задачах. что сейчас нужно изменить в уже имеющемся коде? да нет же. в данный момент, я именно в ступоре. даже не могу понять что делать дальше. Добавлено через 50 секунд да. просто объясните, что и как должно быть? |
Автор: mes 26.10.2010, 21:16 |
у вас есть возможность проверять и клиент и сервер ? то есть как я понял у Вас есть (если все лишнее выкинуть) фактически пустые клиент и сервер на основе сокетов ? Добавлено @ 21:16 задаю вопросы по частям чтоб не уйти в сторону.. |
Автор: boostcoder 26.10.2010, 21:19 | ||||
да. сейчас это пустой каркас. для тестов, обработчики заполнил хламом:
|
Автор: mes 26.10.2010, 21:28 | ||
выкиньте хлам.. добавьте две структуры query и result с разными id сделайте два сендера один может отправлять query в сокет, другой result а также два простых получателя, (для каждого по одному сообщению) печатающих допустим id и разместите соответсвенно одну пару на клиенте , другую на сервере.. ничего лишнего, только самое необходимое.. жду (результата или вопросов) ![]() |
Автор: boostcoder 26.10.2010, 21:40 | ||||
т.е. из тела обработчиков? сами обработчики оставить пустыми? в данный момент, структуры(запросы и ответы) генерируются кодогенератором. так:
т.е. код который вы видите выше, генерируется этим макросом. т.е. изменить этот макрос так, чтоб в нем были две структуры? или две команды? команда - состоит из двух структур: 1)запрос, 2)ответ. так как?
на стороне клиента? т.е. создать два объекта типа client? или как? т.е. на сервере один сендер и один получатель? на клиенте так же? |
Автор: mes 26.10.2010, 21:55 | ||||
без каких либо обработчиков и без применения всего мудренного 5ти строчные объекты.. сейчас времени нет, чуть позже напишу... Добавлено через 31 секунду
ага ![]() |
Автор: mes 26.10.2010, 22:31 | ||
можно даже не два объекта, а две функции вот к примеру :
терь нужно оживить это... на клиенте и на севере подобная конструкция чтоб клиент отправлял серверу query, а тот в ответ result.. и еще раз, никаких макросов и кодогенераторов на этом этапе.. |
Автор: boostcoder 26.10.2010, 22:40 |
ок. понял. сделаю. Добавлено через 9 минут и 29 секунд чтение/запись сделать асинхронными? |
Автор: boostcoder 26.10.2010, 22:55 |
если я все верно понял, то вы хотите реализовать запись и чтение в один сокет на каждой стороне? это получится что-то вроде RS-триггера на каждой стороне. т.е. когда клиент записывает в сокет, на стороне сервера получаем событие записи и читаем из сокета. в то время, если сервер пишет, то событие записи получаем на стороне клиента. все верно? Добавлено через 52 секунды идея ![]() |
Автор: mes 26.10.2010, 23:03 | ||||
ага ![]()
оказывается проблема сидела глубже чем я думал.. ![]()
ага ![]() я даже боюсь представить как у вас было раньше.. ![]() |
Автор: boostcoder 26.10.2010, 23:11 |
![]() сервер создавал сокет при подключении и ждал записи со стороны клиента. клиент, после того как записал серверу, ожидал записи со стороны сервера ![]() |
Автор: mes 26.10.2010, 23:21 | ||
ну в принципе я так и подумал.. просто не смог представить, как вы даже чат на таком реализовывать будете.. ( а по видимым кускам, там нечто по сложнее чем чистый чат) ![]() зато хоть все стало становиться на свои места... понятно что вставляло палки в колеса понимания ![]() |
Автор: boostcoder 26.10.2010, 23:25 |
да..с проектированием у меня есть проблемы. исправляюсь. читаю умные книжки. наверное еще пол часика и будет код. |
Автор: boostcoder 27.10.2010, 02:33 | ||||||||
вот. даже работает ![]() честно признаюсь, я догадывался что оно должно работать именно так, потому и создал на днях http://forum.vingrad.ru/forum/topic-312737.html тему. но что-то меня отвлекло.. сервер:
собирать так:
клиент:
собирать так:
|
Автор: mes 27.10.2010, 08:51 | ||
![]() итак старт положен.. "сырые" данные можете отправлять.. чтоб не путаться назовем объекты этого уровня net_client и net_server.. теперь создаем еще одного clienta, который будет посредством net_client`a отправлять уже типизированные сообщения.. и еще один сервер, который на основе net_servera будет по id в карте вызывать нужный диспетчер для начала диспетчер такого вида :
|
Автор: boostcoder 27.10.2010, 15:59 |
в следующем варианте, и клиент и сервер, изначально должны находится в режиме чтения. так? зы вот теперь я точно понял идею ) |
Автор: mes 27.10.2010, 16:25 | ||
речь идет о сокетах ? вообще то должны быть в режиме ожидания, готовые к двусторонней передаче.. т.е как для записи, так и для чтения.. ( я говорю с точки зрения пользователя сокета.. как там внутри я не знаю ) |
Автор: boostcoder 27.10.2010, 16:29 |
т.е. после подключения, клиент и сервер становятся в операцию асинхронного чтения на сокете? полагаю, так логичнее. т.к. изначально мы не зависим от того, кто ведущий а кто ведомый. и любой из них может первым послать пакет. |
Автор: mes 27.10.2010, 16:30 | ||||
вобще-то это уже будет не сервер..а сессия (или удаленный client.. ) но так как у нас (насколько я понял) сервер на одного клиента, то пока пойдет, потом будет виднее где подправить ![]() Добавлено @ 16:31 ![]() я был против выражения "установлен на чтение", так как тогда логически не возможна запись.. но если не воспринимать буквально, то все верно ![]() Добавлено через 3 минуты и 9 секунд
значит все таки столько страниц темы были не напрасны ![]() |
Автор: boostcoder 27.10.2010, 16:34 |
к примеру: клиент подключился к серверу. оба читают из сокета. сервер производит запись. но т.к. клиент ожидает записи в сокет, он читает пакет, снова становится в режим чтения, что-то выполняет с прочитанным пакетом. так? еще любопытно, каким образом можно реализовать пакеты двух типов? т.е. пакеты на которые нужно посылать ответ, и пакеты без ответов? Добавлено через 7 минут и 38 секунд ![]() |
Автор: mes 27.10.2010, 16:50 | ||||
висят себе два сокета никого не трогют, в один написали, друг подал сигнал, и его прочитали.. ![]() Добавлено через 30 секунд
никаким образом этого не нужно ( и не придется) делать ![]() |
Автор: boostcoder 27.10.2010, 16:53 | ||
ну да. ок. сейчас код выдам. |
Автор: boostcoder 28.10.2010, 00:21 | ||||
если я все правильно понял, то вот. код компилиться, но не завершен, т.к. некоторые моменты не ясны. а именно: 1. клиент, при посылке команды, каким образом будет знать, на какую команду ждать ответа, а на какую нет? 2. серверу, чтоб послать ответ на какую-то команду, так же как и клиенту нужно знать, на какую команду отвечать, а на какую нет. хидер:
реализация:
|
Автор: mes 28.10.2010, 08:36 | ||
опять )) ничего лишнего ! ) только то что было в задании ) ну ладно .. сервер не посылает ответ, как таковой, он просто принимает команды и работает и побрабатывает их.. если ему когда нибудь (в зависмости от логики обработки, и независимо от приема команды клиента) захочеться послать клиенту команду, он просто ее посылает.. ![]() сейчас код гляну Добавлено через 14 минут и 47 секунд посмотрел.. как и предполагалось по вступительным вопросам к коду.. опять вставили свою лепту.. ![]() ну в принципе ничего так, только надо вытащить нужное, и избавиться от лишнего.. |
Автор: mes 28.10.2010, 08:59 |
по коду я понял, что у вас предполагается одинаковая база как для сервера, так и для клиента? это жесткая привязка, которая может заставить пользователя писать костыль.. это у Вас моноблок получается.. нехорошо.. к инвокерам претензий в принципе нет |
Автор: mes 28.10.2010, 09:17 | ||||
пока оставим сервер в покое.. принимает - молодец, с него пока хватит.. (только к клиенту этот подход не применять, и не отходить от нашего нижепредложенного плана ) рассмотрим net_client... нам важны сейчас две его функции , отправки и приема сырых данных.. сырые данные (исходя из кода) у нас выражены как (header&, body&) на клиентена надо добавить два объекта.. rpc_sender и rpc_receiver выглядят так
привязка к net_clientу посредством bind. для проверки можно связать сендер и ресивер непосредственно .. и еще раз ничего лишнего ! ![]() фактически только реализовать сендер и привязку.. |
Автор: boostcoder 28.10.2010, 09:51 | ||||
это правда. я забежал вперед. просто в момент написания, мне казалось что идею я понял целиком..но когда дошло дело до отправки ответа, я понял, что ничего не понял..
т.е. команды для клиента и сервера разные? не связанные между собой? от чего именно избавится?
это именно тот момент, из-за которого я недописал реализацию. ага. не могли бы вы изменить код приведенный выше, так, чтоб в нем небыло ничего лишнего? т.к. я не очень понимаю что именно я должен сделать.. Добавлено через 1 минуту и 20 секунд по последнему: вроде понял.. Добавлено через 3 минуты и 2 секунды т.е. мой код. |
Автор: mes 28.10.2010, 10:56 | ||||
![]() |
Автор: boostcoder 28.10.2010, 10:58 |
ок. Добавлено через 3 минуты и 48 секунд по приему данных все ок. в коде сервера, в строке 77, заголовок и тело прочитаны. можно диспетчеризировать. отправку пока оставим в покое я так понял. сейчас клиента доделаю. |
Автор: mes 28.10.2010, 11:13 | ||||||
при простой модели ( точка <-> точка ) команды симметричны т.е. что у одного для отправки у другого для приема.. Добавлено через 4 минуты и 10 секунд
имелось ввиду что не важен сам процесс отправки, и другие функции такие как подключение.. наш rpc_sender с ресивером могут работать в том числе и без сетевого клиента ( если взаимодействие не через сеть).. но это опять забегание вперед, для того чтоб немножко снизить туманость на пути к цели ![]() Добавлено через 14 минут и 42 секунды
да, только, чтоб можно было диспатчеризовать кому угодно, и развязать нам руки, вместо _impl поставить делегата ![]() |
Автор: boostcoder 28.10.2010, 11:59 | ||
код клиента. только не связал rpc_sender и rpc_receiver, ибо не уверен что все понял..
|
Автор: mes 28.10.2010, 12:02 | ||||
Добавлено через 1 минуту и 29 секунд
нет..
Добавлено через 3 минуты и 11 секунд выкидываем пока клиента... а то Вас так прям и тянет в сторону ... Добавлено через 4 минуты и 52 секунды пишем только сендер и ресивер.. связываем выход сендера, со входом ресивера.. при отправке пользователем тпизированного сообщения, ресивер должен распечать его в сыром виде.. ![]() Добавлено через 5 минут и 54 секунды т.е связаны должны быть raw_send и dispatch ![]() |
Автор: boostcoder 28.10.2010, 12:09 | ||
вот.
|
Автор: mes 28.10.2010, 12:14 |
сейчас да.. после , если захотите избежать лишних копирований, или иметь возможность помещать в очередь ожидания, они пакуются в полиморфный объект (raw_packet) но нам это сейчас лишнее.. Добавлено через 1 минуту и 45 секунд а посмотрел на клиент.. вы не то связали.. raw_send не привязывается к клиенту .. Добавлено через 2 минуты и 17 секунд т.е. не привязывается как хэндлер записи... |
Автор: boostcoder 28.10.2010, 12:16 | ||
т.е. код клиента выкидываем, и в main() связываем только два объекта sender и receiver ? |
Автор: mes 28.10.2010, 12:20 | ||
сейчас да.. чтоб Вы поняли как клиент подключать ![]() |
Автор: boostcoder 28.10.2010, 12:33 | ||
так?
|
Автор: mes 28.10.2010, 12:38 | ||
вобще то так :
|
Автор: boostcoder 28.10.2010, 12:45 |
хорошо. что дальше? |
Автор: mes 28.10.2010, 12:47 |
теперь к ресиверу нужно добавить таблицу диспетчеров.. где dispacther полиморфно принимает сырой пакет, конвертирует его в нужный тип, и отдает делегату .. |
Автор: boostcoder 28.10.2010, 13:02 | ||
так?
|
Автор: mes 28.10.2010, 13:10 | ||||
опять не совсем.. слишком рано для предположения о передачи типизированного сообщения ресиверу... ресивер это чать rpc, a сообщения должны обрабатываться в пользовательской части ..![]() Добавлено через 2 минуты и 45 секунд
|
Автор: boostcoder 28.10.2010, 13:16 | ||||
значит так:
не понимаю к чему это сказано.... |
Автор: mes 28.10.2010, 13:17 | ||
|
Автор: boostcoder 28.10.2010, 13:18 |
я просто не понимаю к чему это должно привести.. может оказаться так, как уже было... что мы четыре страницы не могли понять друг-друга.. |
Автор: mes 28.10.2010, 13:22 | ||
сейчас так и происходит..поэтому я частями и даю.. ![]() ничего скоро уже должно подойти к цели ![]() Добавлено через 1 минуту и 29 секунд добавляем к ресиверу функцию (шаблонную) для регистрации обработчика (сейчас лямбда функции) |
Автор: boostcoder 28.10.2010, 13:37 | ||
ага.
Добавлено @ 13:38 код не компилил. так что использовать как псевдокод. |
Автор: mes 28.10.2010, 13:38 | ||
как сделаете заводите два сообщения query и result и вот тестовый пример :
set_handler это reg. |
Автор: boostcoder 28.10.2010, 13:40 | ||
тут непонятно что использовать как ключ.. или же эту часть должен сгенерировать кодогенератор? Добавлено через 1 минуту и 59 секунд
![]() ![]() |
Автор: mes 28.10.2010, 13:42 | ||||
T::id .. не понял вопроса.. кодогенератора у нас нет пока (мы догаваривались же).. все вручную ![]() Добавлено @ 13:43
что то не так ? ![]() |
Автор: boostcoder 28.10.2010, 13:45 |
все так. еще одно непонимание разрешилось) |
Автор: mes 28.10.2010, 13:45 |
отлично ![]() Добавлено @ 13:47 как тестовый пример заработает, считайте что главное сделали. ![]() Добавлено через 10 минут и 36 секунд как закончите выкладывайте этот примерчик на онлайн-компиляторе.. чтоб можно было визуально оценить куда дальше рельсы класть ![]() |
Автор: mes 28.10.2010, 14:38 |
чего то долговато.. там вроде ж у Вас все готово.. или опять чего то лишнее прикручиваете ?![]() |
Автор: boostcoder 28.10.2010, 14:45 |
![]() вот: http://liveworkspace.org/code/a372e0ad39ad54853d988c17158dc121 что-то компилятор ругается.. Добавлено через 13 минут и 9 секунд не вижу ошибки.. вполне законное связывание.. |
Автор: mes 28.10.2010, 15:03 |
это моя ошибка, в связывании забыты плейсхолдеры ![]() Добавлено через 2 минуты и 19 секунд терь не хватает кода сериализации, чтоб увидеть результат.. ![]() |
Автор: boostcoder 28.10.2010, 15:07 |
ы) http://liveworkspace.org/code/3c9e2679054ce612756b18c4669b1ff3 Добавлено через 18 секунд осталось понять почему нет вывода.. Добавлено через 2 минуты и 4 секунды это спешка.. сейчас сделаю.. |
Автор: boostcoder 28.10.2010, 15:40 |
вот: http://liveworkspace.org/code/e41ca2a8c07fc54bc49cabd172c9e0ab но есть один вопрос не позволяющий завершить код: как быть с meta_dir ? это индикатор направления пакета. Добавлено через 44 секунды убрать пока его? |
Автор: mes 28.10.2010, 15:57 | ||
ну а откуда он взялся ? ![]() ![]() ![]() ![]() Добавлено через 19 секунд сейчас код гляну ![]() |
Автор: mes 28.10.2010, 16:33 |
чего то вы там хидерами и бодями нахимичили.. |
Автор: boostcoder 28.10.2010, 16:36 |
значит не будет ![]() еще с сериализацией разберусь... |
Автор: mes 28.10.2010, 16:57 |
я думаю сейчас пора убраться от лишних зависимостей реализации.. и объединить хидер с бодом в одном пакете.. ![]() |
Автор: boostcoder 28.10.2010, 17:00 |
затайпдефить новый тип? Добавлено через 7 минут и 48 секунд вот: http://liveworkspace.org/code/ae95e786e65835543dbed5ee67d368e5 осталось понять почему не вызывается invoker::dispatch() .. Добавлено через 12 минут и 2 секунды карта почему-то пустая. хотя зарегано по одному обработчику.. |
Автор: boostcoder 28.10.2010, 17:20 |
с этим разобрался: http://liveworkspace.org/code/2da9190f091a4ccbf28913d37ff318ba еще ответ на query не срабатывает ![]() Добавлено через 2 минуты и 47 секунд вот. и с этим разобрался: http://liveworkspace.org/code/43a5b1c35f66f6a6f9868a3941c5a04b гляньте плиз, я ничего не напутал? можно считать этот код опорной точкой для продолжения? Добавлено через 9 минут и 55 секунд и еще: http://liveworkspace.org/code/f936ac96af0b5f32780ef89ab01d68e0 |
Автор: mes 28.10.2010, 17:36 | ||
на вид пока все ок ) не совсем.. нужно избавиться от лишних. зависимостей.. пока эту часть консервируем и делаем от нее ответление.. (вначале все таки упустили, терь придется поправлять) заводим структуру
убираем весь код сериализации в сторону, и вмето хидера_с_бодей ставим нашу структуру.. |
Автор: boostcoder 28.10.2010, 18:11 | ||
каких именно, и каким образом? т.е. на основе этого кода? или писать с нуля?
т.е. эту структуру вписать в другой дополнительный хидер? |
Автор: mes 28.10.2010, 18:16 |
так же как от нет_клиента избавились ![]() зачем с нуля ? сейчас код весь нужный, только неправильно расфасован.. создаете новый файл, перекидываете туда все кроме сериализации и меняете параметры функций на rpc_packet.. нет, грубо говоря сериализацию вынести в другой хидер... ![]() Добавлено через 33 секунды сейчас подождите.. я сам сделаю .. |
Автор: boostcoder 28.10.2010, 18:24 |
ы ![]() |
Автор: mes 28.10.2010, 18:27 |
вот что я просил : http://liveworkspace.org/code/bae836150c287a809bf7a3628db165f3 ![]() |
Автор: boostcoder 28.10.2010, 18:32 |
ага. ок. что теперь? Добавлено через 5 минут и 6 секунд кстати, а зачем нам rpc_packet ? или это новый тип взамен хедера и бади? Добавлено через 6 минут и 29 секунд по идее - да. в нем будут локальные буфера и сериализация/десериализация. ![]() |
Автор: mes 28.10.2010, 18:40 |
терь надо определиться с пакетом.. какое взаимодействие он должен поддерживать.. |
Автор: boostcoder 28.10.2010, 18:44 |
так как в планах у нас есть динамическое создание обработчиков(а по мне, так обработчики должны быть методами класса), в нем должен быть идентификатор класса обработчика. так же, можно реализовать передачу служебных сообщений таких как например, исключения ![]() |
Автор: mes 28.10.2010, 18:46 |
минутку не торопитесь... давайте приведем вначале к стартовой точке.. ![]() |
Автор: boostcoder 28.10.2010, 18:47 |
т.е. после десериализации пакета, определяем ID класса в котором находится обработчик для команды этого типа. просматриваем карту на предмет наличия этого класса. если есть - берем диспетчера этого класса и передаем ему пакет. если нет - бросить исключение клиенту обратно. Добавлено через 33 секунды мысли вслух... |
Автор: mes 28.10.2010, 18:48 |
подумав все таки решил, что rpc_packet это бинарный набор данных... т.е терь возвращаем сериализацию на родину.. только терь она должна внутрь пакета сериализовать.. Добавлено через 28 секунд вы пока с сериализацией мучайтесь, а я пока про ресивер подумаю )) |
Автор: mes 28.10.2010, 19:06 |
и еще invoker нужно занестить в ресивер.. и разгрузить вызов функции инвокера через внешнюю шаблонную функцию.. |
Автор: boostcoder 28.10.2010, 19:16 | ||
эм.. поясните ;) |
Автор: mes 28.10.2010, 19:37 | ||
в принципе пока не обязательно.. имелось ввиду определить его в пространстве ресивера..
|
Автор: boostcoder 28.10.2010, 19:39 | ||
ок. делаю. |
Автор: mes 28.10.2010, 19:43 | ||||||
сделать две шаблонные функции
внести в них всю работу с сериализацией.. а в сендере, ресивере и, соответственно, инвокере передачу пакета осуществлять по константной ссылке..
Добавлено через 1 минуту и 50 секунд названия не очень удачные.. но если ничего лучше не придет в голову, можно пока так оставить ![]() |
Автор: boostcoder 28.10.2010, 19:53 | ||
ок. и это сделаю. Добавлено через 12 минут и 55 секунд это: и это:
так как делать? |
Автор: mes 28.10.2010, 20:14 |
вобще то одно другому не мешает.. покажите что у Вас сейчас |
Автор: boostcoder 28.10.2010, 20:23 |
пока это: http://liveworkspace.org/code/65e326b96f505a6c875cf88e243f2c9b |
Автор: mes 28.10.2010, 20:43 | ||
я думал вы хоть пакет уже добавили.. ![]() Добавлено через 1 минуту и 27 секунд кстати имхо подход не очень верный.. Вы пытаетесь к сериализации добавить пакет... а нужно с другой строны подходить, к пакету добавлять сериализацию ![]() так будет легче и яснее ) |
Автор: boostcoder 28.10.2010, 20:44 |
так я не был уверен что все правильно понял. выше написал. сейчас все будет. |
Автор: mes 28.10.2010, 20:52 | ||||
вот вам протипы пакета и пакетных функций..
вся сериализация должна быть в них .. Добавлено @ 20:55 тогда сендер будет выглядить так :
и является теперь не зависимым от устройства рпц_библиотеки с остальным будет также.. ![]() это я Вам опять немножко из будущего вытащил ![]() |
Автор: boostcoder 28.10.2010, 20:58 |
минутку...ща все будет.. на LWS сделал выше область редактора кода, и размер шрифта помельче. вроде как повместительней должно быть. Добавлено через 14 минут и 31 секунду в ней же должны быть и хедер и бади. так? |
Автор: mes 28.10.2010, 21:16 |
да, если нужны.. и как нужны ) Добавлено через 2 минуты и 18 секунд вот я подправил остальное : http://liveworkspace.org/code/baa9b08e00519c82392bdb22c903daba |
Автор: mes 28.10.2010, 21:31 |
после можно будет написать класс rpc_receiver2, с инвокерами которые будут вызывать не function, а метод класса.. объект класса будет хранить ресивер.. P.S.старый ресивер не выкидывайте.. |
Автор: boostcoder 28.10.2010, 22:01 |
эврика! http://liveworkspace.org/code/661062d84fc5980f8cbe28b7e5403890 сейчас еще пересмотрю код. кодировщик/декодировщик заголовка пакета нужно куда-то всунуть. Добавлено @ 22:02 гляньте пожалуйста, может еще что-то найдете ;) Добавлено через 9 минут и 28 секунд навел порядок: http://liveworkspace.org/code/e1be046e609bab24d44396051e4c81b6 Добавлено через 12 минут и 32 секунды теперь, как я предполагал, rpc_packet::id это идентификатор класса с его обработчиком? |
Автор: mes 28.10.2010, 22:41 | ||||||
а для чего пакету хидер как буффер ?! сделайте лучше возможность сериализации пакета.. Добавлено через 3 минуты и 14 секунд а paket::body нам тоже не нужен статического размера.. и можно заменить на строку/вектор.. Добавлено через 12 минут и 35 секунд
|
Автор: mes 28.10.2010, 22:56 |
как это подправите, можно считать полученное отправной точкой.. |
Автор: boostcoder 28.10.2010, 22:58 |
ок. сейчас.. |
Автор: mes 28.10.2010, 22:58 | ||||
это уровень сети... здесь нам не нужно.. Добавлено @ 23:00 вобщем нужно примерно так :
все остальное (из constants) в мусорку ![]() |
Автор: mes 28.10.2010, 23:37 | ||
не дождался , сам подправил : http://liveworkspace.org/code/aa539e62ca1c9439d0017fe1a180288b ![]() Добавлено @ 23:46 пусть будет здесь, для надежности..
|
Автор: mes 29.10.2010, 00:00 |
теперь осталось сделать контроль пропуска сообщений, чтоб нельзя было отправить чужое сообщение, но уже сейчас можно запихнуть полученое в rpc_parts.h и на этой основе строить клиента.. |
Автор: boostcoder 29.10.2010, 00:44 |
если я ничего не напутал, то здесь ошибочка. в rpc_pack вы не пакуете идентификатор. но при распаковке пакета, нам не известен его идентификатор, и в функции rpc_unpack вы его не распаковываете. или я опять что-то напутал? |
Автор: boostcoder 29.10.2010, 02:50 | ||
вот что у меня получилось:
http://liveworkspace.org/code/487c740c8d6835ca0d30f827a3ef6efc |
Автор: boostcoder 29.10.2010, 03:10 |
насколько я понимаю, указатели на классы обработчики должны находится в карте клиента и сервера. но создавать их в конструкторе клиента и сервера - нехорошо.. во первых - жестко завязано. во вторых - это может мешать архитектуре клиента и сервера. мне кажется логичным, создавать классы-обработчики по запросу, как я уже писал. с утра уже.. |
Автор: boostcoder 29.10.2010, 03:47 |
вот: http://liveworkspace.org/code/e86552b94c9548c9d464261d3bd7d8cf с обработчиками в виде классов. вот только в данный момент нет возможности из обработчика сделать вызов... Добавлено через 2 минуты и 17 секунд нужно утвердить код, и вынести его в отдельный хидер, а то уже прокручивать палец болит) |
Автор: mes 29.10.2010, 08:18 | ||
21я строчка в моем последнем наброске ![]() а в unpack нам не нужен идентификатор, у нас там уже известен тип ![]() |
Автор: mes 29.10.2010, 09:01 | ||||||
и все остальное относящееся к этому зачем ?! откуда такие предположения, что при отправки по сети подойдет этот формат.. зачем вобще привязываться к нему.. заче не типозависимые данные паковать в строку ?! и много много еще камней, которым Вы так и пытаетесь забросать ручей логики кода.. ![]() Добавлено @ 09:04
вот опять опережаете.. у Вас не сформирован скелет проги, а Вы уже тяжести поднимать заставляете ![]() Добавлено @ 09:07
bad_ID будет при проверке среди возможных ид_пакетов.. А так это всего лишь не зарегистрированный handler ![]() Добавлено @ 09:11 ну и толку от такой конструкции ? так и в первый ресивер можно было вместо лямбды пробиндить метод с объектом.. Добавлено @ 09:14 утвержденый код (точнее его база) в сообщении предшествующее этому :
![]() |
Автор: mes 29.10.2010, 09:18 | ||
![]() ![]() ![]() ![]() Вы, как клиент, за сервер решили, каким образом ему обрабатывать свои сообщения ?! ![]() |
Автор: boostcoder 29.10.2010, 12:50 |
хорошо. какая часть того кода остается неизменной, чтоб ее вынести в отдельный файл? |
Автор: mes 29.10.2010, 12:56 | ||
не неизменной, а опорной.. все кроме маин.. |
Автор: boostcoder 29.10.2010, 13:07 | ||
ок. закинул его в отдельный файл. далее используем так:
http://liveworkspace.org/code/93eb6d4eba45dd51bfdc9ede71f34864 |
Автор: mes 29.10.2010, 13:11 |
![]() терь в какую строну двигаемся ? готов выслушать пожелания ![]() |
Автор: boostcoder 29.10.2010, 13:12 |
![]() я думаю что пора реализовать возможность создания обработчиков по запросу сторон. нет? Добавлено через 4 минуты и 18 секунд еще момент... пишу.. |
Автор: mes 29.10.2010, 13:19 | ||
а мне кажется для начала нужно реализовать нормальное клиент серверное взаимодействие на чтоб прочуствовать, что у нас есть, а чего не хватает.. |
Автор: boostcoder 29.10.2010, 13:27 | ||||||||||
я переделываю кодогенератор так, чтоб записывать обработчики следующим образом:
этот способ мне кажется во много раз более понятным, чем, к примеру, прежний:
исходя из этого, предполагаю использовать это так:
как вам такой вариант? какие мысли по этому поводу? но тут есть одно "но"! в таком случае, у нас нет типов команд(по крайней мере явных). т.е. можно кодогенератор реализовать так, чтоб из аргументов методов создавал структуру и присваивал ей ID. дальше не знаю как и что.. Добавлено через 35 секунд
реализовать сетевое взаимодействие? |
Автор: mes 29.10.2010, 13:29 | ||
ну вот опять... рано силы тратите.. |
Автор: boostcoder 29.10.2010, 13:30 | ||||
ок. на потом. |
Автор: mes 29.10.2010, 13:31 |
ага.. чтоб на примере посмотреть, что у нас получилось.. после попробуем реализовать обработчики удобным способом и только после этого можно будет подумать о кодогенераторе.. Добавлено через 56 секунд я тут пока с mpl разбираюсь.. интересная штуковина .. и нам как раз будет кстати ![]() |
Автор: boostcoder 29.10.2010, 13:33 | ||
хорошо. пишу. Добавлено через 1 минуту и 57 секунд
на boost.fusion взгляните. |
Автор: mes 29.10.2010, 13:37 | ||
для начала напишите в таком прообразе :
|
Автор: boostcoder 29.10.2010, 13:49 |
ок. |
Автор: mes 29.10.2010, 13:52 | ||
если я правильно представляю фусион, то он не подходит, так как мне нужен не контейнер разнотипных данных, а контейнер разных типов и операции над ним ![]() Добавлено через 1 минуту и 59 секунд
посмотрел, точно для текущих планов не то.. |
Автор: boostcoder 29.10.2010, 14:12 |
не понял.. Добавлено через 38 секунд вообще-то во fusion несколько типов контейнеров. |
Автор: mes 29.10.2010, 14:14 |
в любом случае их цель хранить данные.. а мне не нужны сейчас данные.. мне нужны пустые типы. ![]() |
Автор: boostcoder 29.10.2010, 14:27 | ||||
я создавал карту типов так:
http://liveworkspace.org/code/26d4922d44f6e2639c66cd6f41aa7257 Добавлено через 1 минуту и 3 секунды
ну да.. тогда mpl ![]() Добавлено через 1 минуту и 41 секунду значит код приведенный выше не актуален. |
Автор: boostcoder 29.10.2010, 16:26 |
в связи с тем, что мне сейчас нужно реализовать передачу/прием пакетов по сети, и как следствие, паковать и распаковывать их, возник следующий вопрос: пакету нужен заголовок для инфы о нем(id типа, и размер тела). при этом, размер заголовка неизменен. так вот.. для десериализации и диспетчеризации пакета при приеме, нам нужно извлечь из него id и размер тела. при том, размер тела нам так же нужен для чтения тела из сети, т.к. его размер не константен. собственно сам вопрос: нам нужны два типа: 1) packet_header, 2) packet_data. так? и еще вопрос: с packet_header - понятно, две целых. а как быть с packet_data? он ведь по сути просто строка. можно затайпдефить. или как? лучше заранее спрошу..а то опять чего-то не так накожу) |
Автор: mes 29.10.2010, 16:38 |
только они не связаны с rpc_packet.. пусть он будет net_packet { header, data }; тут уже можно использовать константные буфферы и делать проверку если rpc_packet не помещается в net_packet ![]() Добавлено через 7 минут и 14 секунд хотя наверно сама структура net_packet лишняя.. так как дата у нас и так есть... серверу нужен общий буфер, и обоим хидер, или даже не хидер , а preamble ![]() |
Автор: boostcoder 29.10.2010, 17:16 |
а нам не нужно передавать/принимать rpc_packet::id ? Добавлено через 50 секунд опять не понимаю... |
Автор: mes 29.10.2010, 17:29 | ||
вот так примерно может выглядит функция отправляющая в сокет :
|
Автор: boostcoder 29.10.2010, 17:29 | ||||
я, заголовок пакета вижу таким:
тип пакета таким:
все. нам нужны две функции для упаковки типа в массив байт, и для распаковки. шаблонные. так же, информационные аксесоры, такие как: get_class_id, get_method_id, get_body_size, get_raw_data |
Автор: mes 29.10.2010, 17:30 |
какое это имеет отношение к нашим net_ или rpc_ ?! |
Автор: boostcoder 29.10.2010, 17:31 | ||
т.е.
? |
Автор: mes 29.10.2010, 17:31 |
rpc_packet не трогать! разве что заменить raw_data на просто data.. или на просто raw.. чтоб не так длинно было.. ![]() Добавлено @ 17:33 нет.. Вы делаете зависимость от конкретной машины... использовать sizeof нельзя.. |
Автор: boostcoder 29.10.2010, 17:34 | ||
в таком случае мы избавляемся от двух типов. остается только один. порядок полей можно изменить, конечно. Добавлено через 40 секунд
ок. |
Автор: mes 29.10.2010, 17:46 | ||
второго типа пакета у нас и так нет, есть только преамбула.. а она отношение имеет только к сетевой передаче.. скрестив их, мало того что увеличиваете связанность, так еще своим предположением в рпц о преамбуле Вы связываете руки net-"разработчику" ![]() |
Автор: boostcoder 29.10.2010, 17:48 |
ок. |
Автор: boostcoder 29.10.2010, 19:08 |
это что? |
Автор: mes 29.10.2010, 19:10 |
с названиями у нас все таки не порядок.. но пока чего то не приходит как это исправить.. ладно пока подождем.. просто высказался. чтоб в голове не держать.. |
Автор: boostcoder 29.10.2010, 19:12 |
с pack.raw_data все понятно. но вот кто такой id в pack.raw_data ? |
Автор: mes 29.10.2010, 19:12 | ||
это опечатка, которая зародилась у меня, а Вы ее подмножили ![]()
нет такого.. id сырья хранит пакет.. ![]() |
Автор: boostcoder 29.10.2010, 19:19 |
понял. |
Автор: boostcoder 29.10.2010, 20:30 | ||||
еще момент.. в классе rpc_sender, в методе send есть такая конструкция:
так вот... т.к. у нас сетевое взаимодействие асинхронное, нам нужно класть объекты в очередь пока они не "пошлются" ![]() сделал так:
с этим все понятно. нас не интересует момент, когда пакет будет реально отправлен. но вот с приемом пакетов есть нюанс.. объект, выполняющий чтение пакета, должен "оповещать" класс rpc_receiver о том, что пакет пришел. для этого, в него нужно передать указатель на метод или функциональный объект. так сойдет? Добавлено через 25 секунд гляньте пожалуйста, с отправкой пакета все гуд? Добавлено через 3 минуты и 2 секунды код не проверял. могут быть ошибки. для того, чтоб мы могли протестировать взаимодействие сетевой части в одном процессе, нужно выполнять asio::io_service::run в потоке. так что не удивляйтесь тому, что в классе клиента и сервера добавятся потоки. |
Автор: mes 29.10.2010, 20:35 | ||||||||||
сейчас гляну.. а Вам если хотите отвлечься , посмотрите набросок : http://liveworkspace.org/code/16a8c06a8c473fc51a16e5f2977fb7f6 на грязь не обращайте.. это черновик.. обратите внимание на класс distributor, и в особенности как идет доставка контролерам клиента.. ![]() Добавлено через 5 минут и 26 секунд
ага..
ну если эта оболочка которая будет добавлена в очередь, то она не sender a holder.. а если это сендер, то он должен брать сообщение из очереди, а не хранить его.. сейчас дальше гляну.. Добавлено через 7 минут и 43 секунды
ну зачем портить было rpc_sender ? он зарезервирован для другой функциональности... если нужно что то для сети создавайте новые типы.. Добавлено через 9 минут и 7 секунд а если боитесь лишних биндеров, они уйдут позже.. но нам они сейчас упрощают композицию.. Добавлено через 11 минут и 31 секунду
да в любом случае он должен иметь ссылку, только вот на ресивер?, или все таки бинд к методу клиента?. Добавлено через 14 минут и 1 секунду
вижу что тот простой трюк ( с биндами ) понравился ![]() ![]() ![]() Добавлено через 14 минут и 39 секунд вроде все просмотрел.. если не на все ответил, уточните ![]() |
Автор: boostcoder 29.10.2010, 20:51 | ||||
этот объект хранит в себе буфер который нужно послать. по этому, эти объекты мы кладем в очередь. в контексте программирования это как переводится?
ок. |
Автор: mes 29.10.2010, 20:53 |
держатель |
Автор: boostcoder 29.10.2010, 20:54 |
мне кажется на ресивер. т.к. именно ресивер содержит карту инвокеров и метод dispatch() его нужно вязать к rpc_receiver::dispatch(rpc_packet const& pack) Добавлено через 1 минуту и 9 секунд ну тогда сложно определиться с его именем. т.к. он и держатель буфера который нужно отправить, и отправитель. Добавлено через 1 минуту и 35 секунд сейчас ваш код усваивать буду.. |
Автор: mes 29.10.2010, 20:55 | ||||
почему не хранить объекты в очереди, а объекту давать ссылку на очередь.. это даст шанс к примеру удалить некоторые пакеты из очереди, если долго не отправляются... (понимаю что такая функциональность не нужна, пример приведен лишь в доказательство логичности предложенного подхода) Добавлено через 1 минуту и 22 секунды если вы пока под "впечатлением" клиента сервера, то не сбивайте настрой.. с другой стороны просмотр позволит заглянуть немного вперед.. я вижу у вас к сожалению нет пока общей картины, кк чему мы стремимся.. Добавлено через 2 минуты и 56 секунд
нет..он не отправляет.. он его хранит и может отдать сокету.. который отправит.. а если б он брал из очереди и отдавал бы , то получился бы сендер.. |
Автор: boostcoder 29.10.2010, 21:00 | ||
поясните.. |
Автор: mes 29.10.2010, 21:01 | ||
1.dispatch принимает рпц_пакет, а с сервера приходит чистый буфер.. заставлять делегата расшифровывать не хорошо.. так как могут потрбоваться знания которыми обладает только клиент.. 2. диспатчеризироваться объект может более чем одному ресиверу (например на выбор) и только клиент знает кому и когда.. |
Автор: boostcoder 29.10.2010, 21:02 | ||||
значит holder Добавлено через 2 минуты и 34 секунды
нужен еще один тип? расшифровщик? тогда нужен и шифровщик, который сейчас у меня в конструкторе real_sender |
Автор: mes 29.10.2010, 21:06 | ||||||
и даже не на очередь а на клиента.. и он даже не сендер , а write_action интуитивно лезет что от типа такого :
хотя может действительно не клиент, а очередь.. трудно сказать.. делайте для начала на очередь.. Добавлено @ 21:07
скорее не типы, а функции, на подобиe pack/unpack сейчас вы шифровку сделаете в одном месте, а расшифровку в другом, потом еще где нибудь добавите.. а потом будете по всему коду искать почему они не симетричны.. а так у вас в одном месте и всегда можно оттестить отдельно от общей массы.. Добавлено @ 21:18 а клиент после отправки асио объекта с ссылкой, может быть уверен, что объект не будет жить дольше клиента ? |
Автор: boostcoder 29.10.2010, 21:43 | ||||||
в деструкторе io_service`а все объекты которые еще лежат в очереди будут разрушены. или я не понял вопроса? Добавлено через 3 минуты и 18 секунд
тут не понял... какого типа ссылка на объект m_client? что подразумевается по словом "клиент" ? и что подразумевается под словом "очередь" ? Добавлено через 3 минуты и 47 секунд
это понял. |
Автор: mes 29.10.2010, 21:55 | ||
ага..так и предполагал .. net_client к примеру стд::очередь рпц_пакетов.. к тому же write_action может сбросить в сокет более одного пакета.. если есть время и место для этого .. |
Автор: boostcoder 29.10.2010, 22:00 | ||
io_service и так представляет очередь. сам выполняет объекты которые в очереди. сам удаляет те, которые выполнил. размер очереди ограничивается только ресурсами системы. зачем нам еще одна очередь? Добавлено через 2 минуты и 9 секунд а если мой вариант реал_сендера переделать так, чтоб он не выполнял упаковку рпц_пакета, чем он не устраивает? Добавлено через 3 минуты и 10 секунд ну и называть его холдером |
Автор: mes 29.10.2010, 22:06 | ||
я не знал, и чего то не подумал о такой возможности.. ![]() тогда ссылка внутри в принципе не нужна.. а отправителя можно обозвать курьером или чем то в этом роде.. а чтоб пакет 100 раз не копировали, можно сделать его коровой... (CopyOnWrite) но потом.. после того как все остальное закончим .. |
Автор: boostcoder 29.10.2010, 22:20 |
методом http://www.boost.org/doc/libs/1_44_0/doc/html/boost_asio/reference/io_service/post.html производится явная ставка объекта в очередь. все остальное что в asio асинхронное, работает таким-же образом, но не явно. по поводу таймаутов на отправку: нет возможности удалить объект из очереди. но это реализуется выбросом исключения из объекта и повторным вызовом run() в catch блоке. читать http://www.boost.org/doc/libs/1_44_0/doc/html/boost_asio/reference/io_service.html#boost_asio.reference.io_service.effect_of_exceptions_thrown_from_handlers. при том, io_service гарантирует, что все остальные объекты продолжат выполняться. но это сейчас нам не нужно. и так работы еще огого) Добавлено через 58 секунд mes, скажите, чем именно мне сейчас заниматься? а то все смешалось в кучу ![]() |
Автор: mes 29.10.2010, 22:23 | ||
ну вот сбил Вас.. :( показывайте что у вас есть.. только не кучей.. для начала покажите как выглядит клиент.. ![]() |
Автор: boostcoder 29.10.2010, 22:34 | ||
вот:
|
Автор: mes 29.10.2010, 22:44 | ||
а пока закиньте плиз это в наш rpc_rev1.hpp
Добавлено @ 22:45 а где методы ?! |
Автор: boostcoder 29.10.2010, 22:45 |
просто вставить в конец файла? Добавлено через 1 минуту и 14 секунд во первых - я еще не закончил. во вторых - мы с вами интенсивно общались последние два часа ![]() |
Автор: mes 29.10.2010, 22:46 |
ага |
Автор: boostcoder 29.10.2010, 22:47 |
кстати, а какие именно методы ему нужны? send() ведь есть) |
Автор: mes 29.10.2010, 22:48 | ||
ну тогда и это чтоб не мешалось в другой файл ( test_ptcl.h)
Добавлено через 1 минуту и 2 секунды под методами я имел ввиду ваши биндеры и ассинхронные агенты.. Добавлено через 3 минуты и 33 секунды помимо send , нужен еще set_handler ресивера.. а также connect, и disconnect.. |
Автор: boostcoder 29.10.2010, 22:55 |
вставил Добавлено через 1 минуту и 45 секунд в этот файл нужно заинклудить rpc-rev1.hpp ? или наоборот? или ничего не инклудить? |
Автор: mes 29.10.2010, 23:01 |
ой сорри.. я там оказывается в дистрибьютере забыл поменять get_target, на rpc_get_target.. Добавлено через 2 минуты и 7 секунд и тут плиз client на C |
Автор: boostcoder 29.10.2010, 23:03 |
это то, что я предлагал http://forum.vingrad.ru/index.php?showtopic=311688&view=findpost&p=2239176 посте? что в них изменить? и как их назвать? send_holder и receive_holder ? |
Автор: mes 29.10.2010, 23:08 | ||||
давайте пока остановимся на :
Добавлено через 40 секунд или даже сократить
|
Автор: boostcoder 29.10.2010, 23:10 | ||
он так и зовется:
сделал. файл test_ptcl.h тоже. Добавлено через 2 минуты и 9 секунд что в них изменить, помимо выноса функций упаковки/распаковки ? |
Автор: mes 29.10.2010, 23:13 |
его я поменял, а вот в invoker::dispatch забыл :( |
Автор: boostcoder 29.10.2010, 23:20 |
сделал. |
Автор: mes 29.10.2010, 23:20 |
я видел только outgo (real_sender), a incoma не было .. Добавлено @ 23:22 спасибо, терь хоть рассмотреть можно.. не крутя километры.. http://liveworkspace.org/code/faebea2999c743443b75f45f1100a42b |
Автор: boostcoder 29.10.2010, 23:23 | ||||
так по поводу него я и спрашивал. и тут возникла дискуссия. продолжавшаяся до недавнего времени ![]()
Добавлено через 1 минуту и 16 секунд
значит это мне к изучению. т.к. предыдущий код который я должен быть понять, я посмотрел только мельком, из-за дискуссии ![]() |
Автор: mes 29.10.2010, 23:28 | ||||
а я думал что вопрос решен :
т.е. желательно связывать через делегата от клиента.. Добавлено через 1 минуту и 21 секунду ну можно так сказать.. ![]() ![]() |
Автор: boostcoder 29.10.2010, 23:32 | ||
скажите, а в этом коде, можно лямбду заменить на функции/методы? а то, честно говоря, я теряюсь из-за невозможности ясно понять кто вызывается ![]() |
Автор: mes 29.10.2010, 23:36 | ||||||
т важные моменты , на которые хотел бы обратить внимание, могу вкратце прокомментировать.. класс клиент (другой клиент, не те которые мы с вами знали, пользовательская часть) может состоять из разных разработчиков, каждый из которых выполняет специализированную работу...
можно и динамически создавать их, но это пока не надо.. каждый обработчик может посылать пакеты, а также получать их.. при этом регистрация обработчиков в ресивере выглядит так
для выполнения метода хранится не инстанс соответсвующего методу типа, а только входная точка (т.е. наш клиент) Добавлено через 39 секунд
лямбды на сервере.. их не смотрите.. смотрите только клиента.. |
Автор: boostcoder 29.10.2010, 23:47 | ||||
с этим понял. вынесу в отдельные функции.
а это нет ![]() Добавлено через 23 секунды хорошо. |
Автор: mes 29.10.2010, 23:50 | ||
на случай если будет больше одного ресивера.. но не обращайте внимание, это опять с философской точки зрения, на практике может не пригодится.. я просто приводя для себя такие примеры определяю логичны ли метод и его месторасположение.. Добавлено @ 23:56 что то мне кажется, то что Вы сейчас делаете, надо называть не нет клиентом, а rpc_tcp_connection и такие соединения подойдут для сервера..которые будут создаваться по приказу акцептора.. Добавлено @ 00:01 и еще добавьте флаг в метод send
|
Автор: boostcoder 30.10.2010, 00:10 | ||||
тут немного иначе все.. этой темой, я задался с целью изменить реализацию протокола. то, что я вам показывал до того как понял что оба участника сессии должны быть равноправными, не плохо работает, на практике. я такой принцип использовал в двух проектах. но последний(текущий) потребовал от прежней реализации обратных колбэков и возможность создавать на сервере объекты по запросу клиента. собственно после этого я понял, что сетевое взаимодействие нужно переписывать с нуля. но логика проекта уже сформирована. и ее менять пока что нет причин. процесс создания сессии пользователя: сервер висит на аксепте. при подключении создается объект сессии пользователя, который существует до момента отключения пользователя. требуется возможность создавать объекты-обработчики по запросу клиента. объекты должны жить все время сессии, а так же, должна быть возможность удалить объект по запросу клиента. объекты клиента - классы с методами обработчиками. классы могут иметь собственные данные члены. так же, должны поддерживаться создание обработчиков с передачей в их конструктор данных со стороны клиента. это то, что мне предстоит реализовать. Добавлено через 38 секунд это хорошая идея ![]() Добавлено через 1 минуту и 12 секунд итак.. нужно собраться с мыслями, и закодить что смогу, сегодня. Добавлено через 3 минуты и 35 секунд
т.е. нужна возможность, при запросе от клиента на создание объекта, так же передать и аргументы в конструктор. |
Автор: mes 30.10.2010, 00:14 |
и как нижесказанное под этой цитатой противоречит вышесказанному ? |
Автор: boostcoder 30.10.2010, 00:20 |
не противоречит. просто аксептор и объект сессии уже есть. Добавлено через 47 секунд ааа. я неправильно вас понял. сорри ![]() |
Автор: mes 30.10.2010, 00:21 | ||
чувствую опять забегание далеко вперед ![]() |
Автор: boostcoder 30.10.2010, 00:25 |
ага ![]() пошел изучать код.. |
Автор: boostcoder 30.10.2010, 00:43 | ||
не могу понять, какого класса этот метод? того, который мне предстоит написать? Добавлено через 1 минуту и 45 секунд еще не знаю как расшифровать sttc с cts и stc понятно. |
Автор: mes 30.10.2010, 00:53 | ||
сейчас он называется net_client.. |
Автор: boostcoder 30.10.2010, 00:55 |
а почему аргумент у него типа rpc_paket, а не T ? |
Автор: mes 30.10.2010, 01:01 | ||
|
Автор: boostcoder 30.10.2010, 01:03 |
ага |
Автор: mes 30.10.2010, 01:03 |
ой сорри.. автоматом написал ![]() |
Автор: boostcoder 30.10.2010, 01:09 |
ок. Добавлено через 5 минут и 50 секунд и то что в комментах, полагаю, нужно использовать? т.е. если флаг == ложь, то диспетчеризируем заново? но тогда несоответствие типов. т.к. rpc_distributor::dispatch принимает rpc_paket я опять не понял? |
Автор: mes 30.10.2010, 01:22 |
если флаг установлен, отправляет серверу, иначе себе.. потому как могут быть пакеты не предназначенные для сервера.. т.е. большой и малый круги кровопакетообращения. хотя я рано это вам предложил.. опять запутал.. Добавлено через 52 секунды угу.. пока тогда оставьте..потом подумаем как .. |
Автор: boostcoder 30.10.2010, 01:24 |
ок. |
Автор: mes 30.10.2010, 01:28 |
по идеи решается установкой двух сендеров, внешнего и локального.. |
Автор: mes 30.10.2010, 01:52 |
но у такого прямого подхода есть недостаток в различном поведении внешних и внутренних отправлений...внутренний круг, будет не ассинхронный, и возможны рекурсивные вызовы.. поэтому вначале надо реализовать этого клиента, чтоб понятно было .. |
Автор: boostcoder 30.10.2010, 01:53 |
реализовываю... но сейчас не закончу. с утра уже.. |
Автор: mes 30.10.2010, 01:56 |
ок. спокойной ночи ![]() |
Автор: boostcoder 30.10.2010, 02:02 |
и вам ![]() |
Автор: mes 30.10.2010, 10:51 |
сейчас вот отклонился на диспатчеризацию сообщения контроллерам.. в основу лег вчерашний дистрибьютор.. http://liveworkspace.org/code/aaf4c9421678bb4a09b522c0dbe5d4ef чтоб не путаться рассматрение идет без внешних элементов ( в том числе сервера) и для начала только один тип сообщения простой - вызов... |
Автор: mes 30.10.2010, 11:21 | ||||
теперь добавлена карта сообщений: http://liveworkspace.org/code/93bbe9011487172275ee4e2130e216d3 в принципе эту часть можно считать законченной... терь осталось посмотреть как прикрутить к сети.. и тогда останется сделать только контроль допуска сообщений в сендере, и сет_хандлере.. ну еще можно будет подумать, как орагнизовывать цепочку дистрибьютеров, но это уже не проблема.. Добавлено через 39 секунд для сохраности выложу тут :
Добавлено через 1 минуту и 29 секунд ну и результат :
Добавлено через 14 минут и 12 секунд хотя нет.. еще есть одна проблемка, для додумывания.. сейчас get_target предполагает, что только один контролер каждого типа бывает.. нужно добавить зависимость от статического ид агента/контролера.. |
Автор: mes 30.10.2010, 12:02 | ||||
вот в необлагороженном варианте : http://liveworkspace.org/code/c1d2db5ef56341d2fc691b0a0e317e2c
а для доведения ума, уже нужен будет mpl .. Добавлено @ 12:10 boostcoder, и как время будет, добавьте плиз, в структуры тестового протокола пару дата_членов с сериализаций.. для тестирования.. Добавлено @ 12:16 и да кстати, как у нас там дела с клиентом.. не думаю что там столько дел, наверно опять не то пишете.. по идеи две структуры инком, оутго пару фунцкий для связывания сигналов, и парочка для связки с рпц.. думаю стоит показать ![]() |
Автор: mes 30.10.2010, 14:05 |
начал ознакомление с буст::асио.. классная вещь - даже лучше , чем я о ней думал.. и для теста нашего рпц_соединения на основе асио, нам даже сокет и сервер не нужен ![]() сейчас только времени нет набросать пример.. ( ![]() |
Автор: boostcoder 30.10.2010, 17:06 | ||
я тут ![]() в тестовые структуры вписал свойства и сериализацию. далее..щас прочту новые посты. Добавлено через 50 секунд
какой-то shared объект использовать? Добавлено через 6 минут и 8 секунд у всех тестовых стркутур два свойства: 1) std::string : msg, 2) int : code в конструкторах порядок такой: (std::string, int) |
Автор: boostcoder 30.10.2010, 17:21 | ||
тут все понятно. |
Автор: mes 30.10.2010, 18:47 | ||
спс ![]() грубо говоря использовать асио просто как асинхронную очередь, без всяких сокетов.. ![]() Добавлено через 18 секунд сейчас дело как раз за ним.. Добавлено через 33 секунды за асио всмысле.. |
Автор: boostcoder 30.10.2010, 18:54 | ||
я уже почти закончил с сокетами. давайте все же доведу эту часть до конца ;) |
Автор: mes 30.10.2010, 18:57 | ||
а я и не предлагал забрасывать сокеты ![]() я просто предложил еще один альтернативный вариант ![]() |
Автор: boostcoder 30.10.2010, 19:26 | ||
гляньте пока класса inkom и outgo
с rpc_sender`ом и outgo вроде все гуд. а вот с inkom и rpc_receiver`ом не все так гладко. что-то мне кажется что тут оверхеда полно.. |
Автор: mes 30.10.2010, 19:34 | ||||
делайте пока с оверхедом, потом лишнее выкинем.. ) код гляну позже сейчас ухожу.. Добавлено через 3 минуты и 19 секунд не удержался, глянул
что это за изобретательство в инкоме ? это не его задача ! |
Автор: boostcoder 30.10.2010, 20:09 |
это не в инкоме. это в rpc_receiver |
Автор: mes 30.10.2010, 20:14 |
тогда что socket делает в ресивере ?! ![]() Добавлено через 2 минуты и 38 секунд при получении событии на чтение, вызывается инком, который считывает хидер (или преамбулу) и тело, формирует rpc_packet и выбрасывает его .. больше ничего ему не нужно.. |
Автор: boostcoder 30.10.2010, 20:18 | ||
оффтоп
еще гляньте блог автора asio: http://blog.think-async.com/ мне особенно понравилась его http://blog.think-async.com/2009/08/composed-operations-coroutines-and-code.html для использования совместно с asio. на тот случай, если вдруг понадобится имитировать несколько тысяч потоков. Добавлено через 2 минуты и 28 секунд ну инкому ведь как-то нужно передать сокет. ок. переделаю. но все равно в конструктор ресивера нужно передать сокет.. Добавлено через 4 минуты и 14 секунд сокет все равно нужен. откуда инкомам передавать его? Добавлено через 5 минут и 41 секунду у сендера ведь есть сокет. почему его не должно быть у ресивера? Добавлено через 10 минут и 16 секунд чтоб получить событие чтения, нам нужно в сервайс впихнуть инком который и вернет rpc_packet в dispatch |
Автор: mes 30.10.2010, 20:31 | ||||
да? я не видел... а ему зачем, можно же связать биндом с нужной функцией ? Добавлено через 1 минуту и 38 секунд
ага.. он будет мостиком, по которому по событию из сокета прибудет наш пакет.. Добавлено через 4 минуты и 26 секунд глянул на сендер.. Вы решили из за того что он пустой можно его заново переписать..а уже выше говорилось, что он сейчас пустой, дальеше в нем появиться функциональнасть позволающая отправлять только "прорегистированные"данные.. |
Автор: boostcoder 30.10.2010, 20:37 |
так... конструктор инкома берет три аргумента: 1) сокет, 2) ссылку на rpc_packet(чтоб избежать копирования), 3) функциональный объект который будет выполнен по прочтению rpc_packet что не так? |
Автор: mes 30.10.2010, 20:37 | ||
из того, что сейчас находится в rpc-rev1.hpp ничего приспосабливать под знания асио не нужно.. если нужно что то, не бойтесь расплодить тип.. их потом легче срезать.. чем один тип разбивать на множество.. Добавлено через 3 минуты и 4 секунды
функциональному объекту он будет передан по константной ссылке ? зачем тогда бояться копирования которого и так не будет.. я уже выше говорил оверхеда типа копирования на нашем этапе бояться не стоит.. это все легко чиститься по окончанию.. к тому же при выровненной конструкции обычно даже и чистить нечего ![]() Добавлено через 3 минуты и 32 секунды остальное в написанном все так |
Автор: boostcoder 30.10.2010, 20:41 | ||
хорошо... сендер мне нужен был чтоб реализовать net_client и net_server. ок. предположим что сендер уже не нужен. кто тогда будет отправлять команды? еще вчера он был нужен... |