@@ -477,6 +477,99 @@ namespace gz
477
477
return true ;
478
478
}
479
479
480
+ // ////////////////////////////////////////////////
481
+ template <typename RequestT, typename ReplyT>
482
+ bool Node::Request (
483
+ const std::string &_topic,
484
+ const RequestT &_request,
485
+ std::function<void (const ReplyT &_reply, const bool _result)> &_cb,
486
+ const char *_repType)
487
+ {
488
+ auto rep = gz::msgs::Factory::New (_repType);
489
+ if (!rep)
490
+ {
491
+ std::cerr << " Unable to create response of type["
492
+ << _repType << " ].\n " ;
493
+ return false ;
494
+ }
495
+
496
+ // Topic remapping.
497
+ std::string topic = _topic;
498
+ this ->Options ().TopicRemap (_topic, topic);
499
+
500
+ std::string fullyQualifiedTopic;
501
+ if (!TopicUtils::FullyQualifiedName (this ->Options ().Partition (),
502
+ this ->Options ().NameSpace (), topic, fullyQualifiedTopic))
503
+ {
504
+ std::cerr << " Service [" << topic << " ] is not valid." << std::endl;
505
+ return false ;
506
+ }
507
+
508
+ bool localResponserFound;
509
+ IRepHandlerPtr repHandler;
510
+ {
511
+ std::lock_guard<std::recursive_mutex> lk (this ->Shared ()->mutex );
512
+ localResponserFound = this ->Shared ()->repliers .FirstHandler (
513
+ fullyQualifiedTopic,
514
+ _request.GetTypeName (),
515
+ rep->GetTypeName (),
516
+ repHandler);
517
+ }
518
+
519
+ // If the responser is within my process.
520
+ if (localResponserFound)
521
+ {
522
+ // There is a responser in my process, let's use it.
523
+ bool result = repHandler->RunLocalCallback (_request, *rep);
524
+
525
+ _cb (*rep, result);
526
+ return true ;
527
+ }
528
+
529
+ // Create a new request handler.
530
+ std::shared_ptr<ReqHandler<RequestT, ReplyT>> reqHandlerPtr (
531
+ new ReqHandler<RequestT, ReplyT>(this ->NodeUuid ()));
532
+
533
+ // Insert the request's parameters.
534
+ reqHandlerPtr->SetMessage (&_request);
535
+
536
+ // Set the response message (to set the type info).
537
+ reqHandlerPtr->SetResponse (rep.get ());
538
+
539
+ // Insert the callback into the handler.
540
+ reqHandlerPtr->SetCallback (_cb);
541
+
542
+ {
543
+ std::lock_guard<std::recursive_mutex> lk (this ->Shared ()->mutex );
544
+
545
+ // Store the request handler.
546
+ this ->Shared ()->requests .AddHandler (
547
+ fullyQualifiedTopic, this ->NodeUuid (), reqHandlerPtr);
548
+
549
+ // If the responser's address is known, make the request.
550
+ SrvAddresses_M addresses;
551
+ if (this ->Shared ()->TopicPublishers (fullyQualifiedTopic, addresses))
552
+ {
553
+ this ->Shared ()->SendPendingRemoteReqs (fullyQualifiedTopic,
554
+ _request.GetTypeName (), rep->GetTypeName ());
555
+ }
556
+ else
557
+ {
558
+ // Discover the service responser.
559
+ if (!this ->Shared ()->DiscoverService (fullyQualifiedTopic))
560
+ {
561
+ std::cerr << " Node::Request(): Error discovering service ["
562
+ << topic
563
+ << " ]. Did you forget to start the discovery service?"
564
+ << std::endl;
565
+ return false ;
566
+ }
567
+ }
568
+ }
569
+
570
+ return true ;
571
+ }
572
+
480
573
// ////////////////////////////////////////////////
481
574
template <typename ReplyT>
482
575
bool Node::Request (
0 commit comments