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